|
@@ -11,7 +11,9 @@ 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.CloudPollResult;
|
|
|
import com.usky.issue.service.vo.SyncPacket;
|
|
import com.usky.issue.service.vo.SyncPacket;
|
|
|
|
|
+import com.usky.issue.service.vo.SyncPollRequest;
|
|
|
import com.usky.issue.service.vo.SyncResponse;
|
|
import com.usky.issue.service.vo.SyncResponse;
|
|
|
|
|
+import com.usky.issue.service.util.ApiResultParser;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
|
|
import org.springframework.http.HttpEntity;
|
|
import org.springframework.http.HttpEntity;
|
|
@@ -136,46 +138,55 @@ public class CloudPlatformClient {
|
|
|
try {
|
|
try {
|
|
|
String credential = aesGcmCipher.decrypt(config.getCredentialKey());
|
|
String credential = aesGcmCipher.decrypt(config.getCredentialKey());
|
|
|
HttpHeaders headers = buildAuthHeaders(config, credential);
|
|
HttpHeaders headers = buildAuthHeaders(config, credential);
|
|
|
- String url = UriComponentsBuilder
|
|
|
|
|
- .fromHttpUrl(resolveIntegrationBaseUrl(config) + CloudIntegrationConstants.PATH_SYNC_POLL)
|
|
|
|
|
- .queryParam("tenantId", tenantId)
|
|
|
|
|
- .queryParam("tableName", tableName)
|
|
|
|
|
- .queryParam("lastVersion", lastVersion == null ? 0L : lastVersion)
|
|
|
|
|
- .queryParam("forceBackfill", forceBackfill)
|
|
|
|
|
- .toUriString();
|
|
|
|
|
|
|
+ headers.setContentType(MediaType.APPLICATION_JSON);
|
|
|
|
|
+
|
|
|
|
|
+ SyncPollRequest pollRequest = new SyncPollRequest();
|
|
|
|
|
+ pollRequest.setTenantId(String.valueOf(tenantId));
|
|
|
|
|
+ pollRequest.setTableName(tableName);
|
|
|
|
|
+ pollRequest.setLastVersion(lastVersion == null ? 0L : lastVersion);
|
|
|
|
|
+ pollRequest.setForceBackfill(forceBackfill);
|
|
|
|
|
+ String requestBody = OBJECT_MAPPER.writeValueAsString(pollRequest);
|
|
|
|
|
|
|
|
- log.info("[pollCloud] 请求 url={}, tenantId={}, tableName={}, lastVersion={}, forceBackfill={}, hasToken={}",
|
|
|
|
|
|
|
+ String url = resolveIntegrationBaseUrl(config) + CloudIntegrationConstants.PATH_SYNC_POLL;
|
|
|
|
|
+ log.info("[pollCloud] POST url={}, tenantId={}, tableName={}, lastVersion={}, forceBackfill={}, hasToken={}",
|
|
|
url, tenantId, tableName, lastVersion, forceBackfill,
|
|
url, tenantId, tableName, lastVersion, forceBackfill,
|
|
|
StringUtils.hasText(CloudEntitySupport.resolveAccessToken(config)));
|
|
StringUtils.hasText(CloudEntitySupport.resolveAccessToken(config)));
|
|
|
|
|
|
|
|
ResponseEntity<String> response = restTemplate.exchange(
|
|
ResponseEntity<String> response = restTemplate.exchange(
|
|
|
- url, HttpMethod.GET, new HttpEntity<>(headers), String.class);
|
|
|
|
|
- String body = response.getBody();
|
|
|
|
|
- if (!StringUtils.hasText(body)) {
|
|
|
|
|
- return CloudPollResult.builder().requestFailed(true).errorMessage("云端返回空响应").build();
|
|
|
|
|
- }
|
|
|
|
|
- log.info("[pollCloud] 响应 status={}, bodyLength={}", response.getStatusCodeValue(), body.length());
|
|
|
|
|
|
|
+ url, HttpMethod.POST, new HttpEntity<>(requestBody, headers), String.class);
|
|
|
|
|
+ return parsePollResponse(response.getBody());
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("[pollCloud] 轮询云端失败 tenantId={}, tableName={}", tenantId, tableName, e);
|
|
|
|
|
+ return CloudPollResult.builder().requestFailed(true).errorMessage(e.getMessage()).build();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ private CloudPollResult parsePollResponse(String body) {
|
|
|
|
|
+ if (!StringUtils.hasText(body)) {
|
|
|
|
|
+ return CloudPollResult.builder().requestFailed(true).errorMessage("云端返回空响应").build();
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("[pollCloud] 响应 body={}", body);
|
|
|
|
|
+ try {
|
|
|
JsonNode json = OBJECT_MAPPER.readTree(body);
|
|
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("认证");
|
|
|
|
|
|
|
+ if (!ApiResultParser.isSuccess(json)) {
|
|
|
|
|
+ String msg = ApiResultParser.resolveMessage(json);
|
|
|
|
|
+ log.warn("[pollCloud] 业务失败 msg={}", msg);
|
|
|
|
|
+ boolean authFailed = msg != null && (msg.contains("认证") || msg.contains("令牌"));
|
|
|
return CloudPollResult.builder()
|
|
return CloudPollResult.builder()
|
|
|
.authFailed(authFailed)
|
|
.authFailed(authFailed)
|
|
|
.requestFailed(true)
|
|
.requestFailed(true)
|
|
|
- .errorMessage(StringUtils.hasText(msg) ? msg : "poll 失败 code=" + code)
|
|
|
|
|
|
|
+ .errorMessage(StringUtils.hasText(msg) ? msg : "poll 调用失败")
|
|
|
.build();
|
|
.build();
|
|
|
}
|
|
}
|
|
|
- JsonNode dataNode = json.has("data") ? json.get("data") : json;
|
|
|
|
|
|
|
+ JsonNode dataNode = json.has("data") ? json.get("data") : null;
|
|
|
if (dataNode == null || dataNode.isNull()) {
|
|
if (dataNode == null || dataNode.isNull()) {
|
|
|
return CloudPollResult.builder().packet(null).build();
|
|
return CloudPollResult.builder().packet(null).build();
|
|
|
}
|
|
}
|
|
|
SyncPacket packet = OBJECT_MAPPER.treeToValue(dataNode, SyncPacket.class);
|
|
SyncPacket packet = OBJECT_MAPPER.treeToValue(dataNode, SyncPacket.class);
|
|
|
return CloudPollResult.builder().packet(packet).build();
|
|
return CloudPollResult.builder().packet(packet).build();
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
- log.error("[pollCloud] 轮询云端失败 tenantId={}, tableName={}", tenantId, tableName, e);
|
|
|
|
|
- return CloudPollResult.builder().requestFailed(true).errorMessage(e.getMessage()).build();
|
|
|
|
|
|
|
+ log.error("[pollCloud] 响应解析失败 body={}", body, e);
|
|
|
|
|
+ return CloudPollResult.builder().requestFailed(true).errorMessage("响应解析失败: " + e.getMessage()).build();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|