|
@@ -4,10 +4,12 @@ import com.fasterxml.jackson.databind.JsonNode;
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import com.usky.issue.domain.IssueCloudConfig;
|
|
import com.usky.issue.domain.IssueCloudConfig;
|
|
|
import com.usky.issue.service.constant.CloudIntegrationConstants;
|
|
import com.usky.issue.service.constant.CloudIntegrationConstants;
|
|
|
|
|
+import com.usky.issue.service.support.CloudEntitySupport;
|
|
|
import com.usky.issue.service.util.AesGcmCipher;
|
|
import com.usky.issue.service.util.AesGcmCipher;
|
|
|
import com.usky.issue.service.util.CredentialMaskUtil;
|
|
import com.usky.issue.service.util.CredentialMaskUtil;
|
|
|
import com.usky.issue.service.util.HmacSignUtil;
|
|
import com.usky.issue.service.util.HmacSignUtil;
|
|
|
import com.usky.issue.service.vo.CloudConnectionTestResult;
|
|
import com.usky.issue.service.vo.CloudConnectionTestResult;
|
|
|
|
|
+import com.usky.issue.service.vo.CloudPollResult;
|
|
|
import com.usky.issue.service.vo.SyncPacket;
|
|
import com.usky.issue.service.vo.SyncPacket;
|
|
|
import com.usky.issue.service.vo.SyncResponse;
|
|
import com.usky.issue.service.vo.SyncResponse;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
@@ -101,7 +103,8 @@ public class CloudPlatformClient {
|
|
|
}
|
|
}
|
|
|
try {
|
|
try {
|
|
|
String credential = aesGcmCipher.decrypt(config.getCredentialKey());
|
|
String credential = aesGcmCipher.decrypt(config.getCredentialKey());
|
|
|
- return testConnection(config.getCloudAddress(), config.getTenantId(), credential, config.getToken());
|
|
|
|
|
|
|
+ String token = CloudEntitySupport.resolveAccessToken(config);
|
|
|
|
|
+ return testConnection(config.getCloudAddress(), config.getTenantId(), credential, token);
|
|
|
} catch (Exception ex) {
|
|
} catch (Exception ex) {
|
|
|
log.error("凭证解密失败 tenantId={}", config.getTenantId(), ex);
|
|
log.error("凭证解密失败 tenantId={}", config.getTenantId(), ex);
|
|
|
return CloudConnectionTestResult.failure(false, "凭证解密失败");
|
|
return CloudConnectionTestResult.failure(false, "凭证解密失败");
|
|
@@ -128,7 +131,8 @@ public class CloudPlatformClient {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public SyncPacket pollCloud(Integer tenantId, String tableName, Long lastVersion, IssueCloudConfig config) {
|
|
|
|
|
|
|
+ public CloudPollResult pollCloud(Integer tenantId, String tableName, Long lastVersion,
|
|
|
|
|
+ IssueCloudConfig config, boolean forceBackfill) {
|
|
|
try {
|
|
try {
|
|
|
String credential = aesGcmCipher.decrypt(config.getCredentialKey());
|
|
String credential = aesGcmCipher.decrypt(config.getCredentialKey());
|
|
|
HttpHeaders headers = buildAuthHeaders(config, credential);
|
|
HttpHeaders headers = buildAuthHeaders(config, credential);
|
|
@@ -137,22 +141,41 @@ public class CloudPlatformClient {
|
|
|
.queryParam("tenantId", tenantId)
|
|
.queryParam("tenantId", tenantId)
|
|
|
.queryParam("tableName", tableName)
|
|
.queryParam("tableName", tableName)
|
|
|
.queryParam("lastVersion", lastVersion == null ? 0L : lastVersion)
|
|
.queryParam("lastVersion", lastVersion == null ? 0L : lastVersion)
|
|
|
|
|
+ .queryParam("forceBackfill", forceBackfill)
|
|
|
.toUriString();
|
|
.toUriString();
|
|
|
|
|
|
|
|
|
|
+ log.info("[pollCloud] 请求 url={}, tenantId={}, tableName={}, lastVersion={}, forceBackfill={}, hasToken={}",
|
|
|
|
|
+ url, tenantId, tableName, lastVersion, forceBackfill,
|
|
|
|
|
+ StringUtils.hasText(CloudEntitySupport.resolveAccessToken(config)));
|
|
|
|
|
+
|
|
|
ResponseEntity<String> response = restTemplate.exchange(
|
|
ResponseEntity<String> response = restTemplate.exchange(
|
|
|
url, HttpMethod.GET, new HttpEntity<>(headers), String.class);
|
|
url, HttpMethod.GET, new HttpEntity<>(headers), String.class);
|
|
|
- if (!StringUtils.hasText(response.getBody())) {
|
|
|
|
|
- return null;
|
|
|
|
|
|
|
+ String body = response.getBody();
|
|
|
|
|
+ if (!StringUtils.hasText(body)) {
|
|
|
|
|
+ return CloudPollResult.builder().requestFailed(true).errorMessage("云端返回空响应").build();
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("[pollCloud] 响应 status={}, bodyLength={}", response.getStatusCodeValue(), body.length());
|
|
|
|
|
+
|
|
|
|
|
+ JsonNode json = OBJECT_MAPPER.readTree(body);
|
|
|
|
|
+ int code = json.has("code") ? json.get("code").asInt(200) : 200;
|
|
|
|
|
+ String msg = json.has("msg") ? json.get("msg").asText() : null;
|
|
|
|
|
+ if (code != 200) {
|
|
|
|
|
+ boolean authFailed = msg != null && msg.contains("认证");
|
|
|
|
|
+ return CloudPollResult.builder()
|
|
|
|
|
+ .authFailed(authFailed)
|
|
|
|
|
+ .requestFailed(true)
|
|
|
|
|
+ .errorMessage(StringUtils.hasText(msg) ? msg : "poll 失败 code=" + code)
|
|
|
|
|
+ .build();
|
|
|
}
|
|
}
|
|
|
- JsonNode json = OBJECT_MAPPER.readTree(response.getBody());
|
|
|
|
|
JsonNode dataNode = json.has("data") ? json.get("data") : json;
|
|
JsonNode dataNode = json.has("data") ? json.get("data") : json;
|
|
|
if (dataNode == null || dataNode.isNull()) {
|
|
if (dataNode == null || dataNode.isNull()) {
|
|
|
- return null;
|
|
|
|
|
|
|
+ return CloudPollResult.builder().packet(null).build();
|
|
|
}
|
|
}
|
|
|
- return OBJECT_MAPPER.treeToValue(dataNode, SyncPacket.class);
|
|
|
|
|
|
|
+ SyncPacket packet = OBJECT_MAPPER.treeToValue(dataNode, SyncPacket.class);
|
|
|
|
|
+ return CloudPollResult.builder().packet(packet).build();
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
- log.error("轮询云端失败", e);
|
|
|
|
|
- return null;
|
|
|
|
|
|
|
+ log.error("[pollCloud] 轮询云端失败 tenantId={}, tableName={}", tenantId, tableName, e);
|
|
|
|
|
+ return CloudPollResult.builder().requestFailed(true).errorMessage(e.getMessage()).build();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -176,7 +199,7 @@ public class CloudPlatformClient {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private HttpHeaders buildAuthHeaders(IssueCloudConfig config, String credential) {
|
|
private HttpHeaders buildAuthHeaders(IssueCloudConfig config, String credential) {
|
|
|
- return buildAuthHeaders(config.getTenantId(), credential, config.getToken());
|
|
|
|
|
|
|
+ return buildAuthHeaders(config.getTenantId(), credential, CloudEntitySupport.resolveAccessToken(config));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private HttpHeaders buildAuthHeaders(Integer tenantId, String credential, String token) {
|
|
private HttpHeaders buildAuthHeaders(Integer tenantId, String credential, String token) {
|