From 175db8f49bbf61effac873d7b0fc1cfd001af287 Mon Sep 17 00:00:00 2001 From: yjj38 Date: Thu, 10 Jul 2025 11:41:50 +0800 Subject: [PATCH] =?UTF-8?q?refactor(device):=20=E9=87=8D=E6=9E=84=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E5=88=97=E8=A1=A8=E6=9F=A5=E8=AF=A2=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=E6=97=A5=E5=BF=97=E8=BE=93=E5=87=BA?= =?UTF-8?q?-=20=E9=87=8D=E5=86=99=20getDeviceCodes=20=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E6=94=B9=E4=B8=BA=20getInstanceListInfo=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8F=82=E6=95=B0=E8=AE=BE=E8=AE=A1=20-=20?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=9C=AA=E4=BD=BF=E7=94=A8=E7=9A=84=20getDev?= =?UTF-8?q?iceInfo=20=E6=96=B9=E6=B3=95=20-=20=E5=9C=A8=E5=85=B3=E9=94=AE?= =?UTF-8?q?=E6=AD=A5=E9=AA=A4=E6=B7=BB=E5=8A=A0=E8=B0=83=E8=AF=95=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E8=BE=93=E5=87=BA=EF=BC=8C=E4=BE=BF=E4=BA=8E=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E6=8E=92=E6=9F=A5=20-=20=E6=9B=B4=E6=96=B0=E7=BD=91?= =?UTF-8?q?=E7=BB=9C=E9=85=8D=E7=BD=AE=EF=BC=8C=E6=B7=BB=E5=8A=A0=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E6=9C=8D=E5=8A=A1=E5=99=A8=20IP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../retention/device/ArmCloudApiClient.java | 239 +++++++++--------- .../device/ChangeDeviceInfoUtil.java | 36 +-- .../com/example/retention/task/TaskUtil.java | 2 +- app/src/main/jniLibs/arm64-v8a/libnative.so | Bin 81480 -> 81488 bytes .../main/res/xml/network_security_config.xml | 1 + 5 files changed, 122 insertions(+), 156 deletions(-) diff --git a/app/src/main/java/com/example/retention/device/ArmCloudApiClient.java b/app/src/main/java/com/example/retention/device/ArmCloudApiClient.java index 862a7ed..7918a06 100644 --- a/app/src/main/java/com/example/retention/device/ArmCloudApiClient.java +++ b/app/src/main/java/com/example/retention/device/ArmCloudApiClient.java @@ -233,11 +233,9 @@ public class ArmCloudApiClient { if (code != 200) { String errorMsg = responseJson.optString("msg", "未知错误"); LogFileUtil.logAndWrite(Log.ERROR, "ArmCloudApiClient", "updateInstanceProperties: 接口返回错误码 " + code + ", 错误信息: " + errorMsg, null); - throw new IOException("接口返回错误码: " + code + ", 错误信息: " + errorMsg); } } else { LogFileUtil.logAndWrite(Log.ERROR, "ArmCloudApiClient", "updateInstanceProperties: 响应中缺少 'code' 字段",null); - throw new IOException("响应中缺少 'code' 字段"); } return responseBodyString; @@ -278,137 +276,130 @@ public class ArmCloudApiClient { } /** - * 分页查询 ARM 设备列表,并提取 deviceCode + * 分页查询实例列表信息 * - * @param page 页码 - * @param rows 每页条数 - * @param padAllocationStatus 实例分配状态:-2删除失败 -1分配失败 0-未分配;1-分配中 2-已分配 3-删除中 - * @param deviceStatus 物理机状态:0-离线;1-在线 - * @param armServerCode 服务器编码 - * @param deviceCode 物理机编号 - * @param deviceIp 物理机IP - * @param armServerStatus 服务器状态:0-离线;1-在线 - * @param idc 机房ID - * @param deviceIpList 板卡IP列表 - * @return 匹配的 deviceCode 数组 - * @throws IOException 请求失败或网络错误 + * @param page 页码 + * @param rows 每页条数 + * @param armServerCode 服务器编号 + * @param deviceCode 板卡编号 + * @param padCodes 实例编号数组 + * @param groupIds 实例分组ID数组 + * @param idc 机房Id + * @return 匹配的 padCode 数组 + * @throws IOException 请求失败或网络错误 */ - public String[] getDeviceCodes( - int page, - int rows, - Integer padAllocationStatus, - Integer deviceStatus, - String armServerCode, - String deviceCode, - String deviceIp, - Integer armServerStatus, - String idc, - String[] deviceIpList) throws IOException { + public String[] getInstanceListInfo( + int page, + int rows, + String armServerCode, + String deviceCode, + String[] padCodes, + Integer[] groupIds, + String idc) throws IOException { - JSONObject json = new JSONObject(); - try { - json.put("page", page); - json.put("rows", rows); + JSONObject json = new JSONObject(); + try { + json.put("page", page); + json.put("rows", rows); - if (padAllocationStatus != null) json.put("padAllocationStatus", padAllocationStatus); - if (deviceStatus != null) json.put("deviceStatus", deviceStatus); - if (armServerCode != null) json.put("armServerCode", armServerCode); - if (deviceCode != null) json.put("deviceCode", deviceCode); - if (deviceIp != null) json.put("deviceIp", deviceIp); - if (armServerStatus != null) json.put("armServerStatus", armServerStatus); - if (idc != null) json.put("idc", idc); - if (deviceIpList != null && deviceIpList.length > 0) { - json.put("deviceIpList", new JSONArray(Arrays.asList(deviceIpList))); - } - - } catch (JSONException e) { - LogFileUtil.logAndWrite(Log.ERROR, "ArmCloudApiClient", "getDeviceCodes: JSON 构建失败", e); - throw new IOException("JSON 构建失败", e); - } - - String jsonBody = json.toString(); - String timestamp = String.valueOf(System.currentTimeMillis()); - String API_PATH = "/openapi/open/device/list"; - - if (secretKey == null || secretKey.isEmpty()) { - throw new IllegalArgumentException("secretKey 不能为空"); - } - - String signature; - try { - signature = calculateSignature(timestamp, API_PATH, jsonBody, secretKey); - } catch (Exception e) { - LogFileUtil.logAndWrite(Log.ERROR, "ArmCloudApiClient", "getDeviceCodes: 签名计算失败", e); - throw new IOException("签名计算失败", e); - } - - RequestBody body = RequestBody.create( - MediaType.get("application/json; charset=utf-8"), - jsonBody - ); - - Request request = new Request.Builder() - .url(baseUrl + API_PATH) - .addHeader("authver", "2.0") - .addHeader("x-ak", accessKey) - .addHeader("x-timestamp", timestamp) - .addHeader("x-sign", signature) - .post(body) - .build(); - - try (Response response = client.newCall(request).execute()) { - if (!response.isSuccessful()) { - throw new IOException("请求失败: " + response); - } - - ResponseBody responseBody = response.body(); - if (responseBody == null) { - throw new IOException("响应体为空"); - } - - String responseBodyString = responseBody.string(); - JSONObject responseJson = new JSONObject(responseBodyString); - - // 校验返回码 - if (responseJson.has("code")) { - int code = responseJson.getInt("code"); - if (code != 200) { - String errorMsg = responseJson.optString("msg", "未知错误"); - LogFileUtil.logAndWrite(Log.ERROR, "ArmCloudApiClient", "getDeviceCodes: 接口返回错误码 " + code + ", 错误信息: " + errorMsg,null); - throw new IOException("接口返回错误码: " + code + ", 错误信息: " + errorMsg); + if (armServerCode != null) json.put("armServerCode", armServerCode); + if (deviceCode != null) json.put("deviceCode", deviceCode); + if (padCodes != null && padCodes.length > 0) { + json.put("padCodes", new JSONArray(Arrays.asList(padCodes))); } - } else { - LogFileUtil.logAndWrite(Log.ERROR, "ArmCloudApiClient", "getDeviceCodes: 响应中缺少 'code' 字段",null); - throw new IOException("响应中缺少 'code' 字段"); - } - - // 提取 deviceCode 列表 - JSONArray pageDataArray = responseJson.optJSONObject("data") - .optJSONArray("pageData"); - - if (pageDataArray == null || pageDataArray.length() == 0) { - LogFileUtil.logAndWrite(Log.WARN, "ArmCloudApiClient", "getDeviceCodes: 查询结果为空",null); - return new String[0]; - } - - int length = pageDataArray.length(); - String[] deviceCodes = new String[length]; - - for (int i = 0; i < length; i++) { - JSONObject item = pageDataArray.getJSONObject(i); - if (!item.has("deviceCode")) { - LogFileUtil.logAndWrite(Log.WARN, "ArmCloudApiClient", "getDeviceCodes: 返回对象缺少 'deviceCode' 字段",null); - throw new IOException("返回对象缺少 'deviceCode' 字段"); + if (groupIds != null && groupIds.length > 0) { + json.put("groupIds", new JSONArray(Arrays.asList(groupIds))); } - deviceCodes[i] = item.getString("deviceCode"); + if (idc != null) json.put("idc", idc); + + } catch (JSONException e) { + LogFileUtil.logAndWrite(Log.ERROR, "ArmCloudApiClient", "getInstanceListInfo: JSON 构建失败", e); + throw new IOException("JSON 构建失败", e); } - return deviceCodes; + String jsonBody = json.toString(); + String timestamp = String.valueOf(System.currentTimeMillis()); + String API_PATH = "/openapi/open/pad/infos"; - } catch (JSONException e) { - LogFileUtil.logAndWrite(Log.ERROR, "ArmCloudApiClient", "getDeviceCodes: 响应解析失败", e); - throw new IOException("响应解析失败", e); + if (secretKey == null || secretKey.isEmpty()) { + throw new IllegalArgumentException("secretKey 不能为空"); + } + + String signature; + try { + signature = calculateSignature(timestamp, API_PATH, jsonBody, secretKey); + } catch (Exception e) { + LogFileUtil.logAndWrite(Log.ERROR, "ArmCloudApiClient", "getInstanceListInfo: 签名计算失败", e); + throw new IOException("签名计算失败", e); + } + + RequestBody body = RequestBody.create( + MediaType.get("application/json; charset=utf-8"), + jsonBody + ); + + Request request = new Request.Builder() + .url(baseUrl + API_PATH) + .addHeader("authver", "2.0") + .addHeader("x-ak", accessKey) + .addHeader("x-timestamp", timestamp) + .addHeader("x-sign", signature) + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + if (!response.isSuccessful()) { + throw new IOException("请求失败: " + response); + } + + ResponseBody responseBody = response.body(); + if (responseBody == null) { + throw new IOException("响应体为空"); + } + + String responseBodyString = responseBody.string(); + JSONObject responseJson = new JSONObject(responseBodyString); + + // 校验返回码 + if (responseJson.has("code")) { + int code = responseJson.getInt("code"); + if (code != 200) { + String errorMsg = responseJson.optString("msg", "未知错误"); + LogFileUtil.logAndWrite(Log.ERROR, "ArmCloudApiClient", "getInstanceListInfo: 接口返回错误码 " + code + ", 错误信息: " + errorMsg, null); + throw new IOException("接口返回错误码: " + code + ", 错误信息: " + errorMsg); + } + } else { + LogFileUtil.logAndWrite(Log.ERROR, "ArmCloudApiClient", "getInstanceListInfo: 响应中缺少 'code' 字段", null); + throw new IOException("响应中缺少 'code' 字段"); + } + + // 提取 padCode 列表 + JSONArray pageDataArray = responseJson.optJSONObject("data") + .optJSONArray("pageData"); + + if (pageDataArray == null || pageDataArray.length() == 0) { + LogFileUtil.logAndWrite(Log.WARN, "ArmCloudApiClient", "getInstanceListInfo: 查询结果为空", null); + return new String[0]; + } + + int length = pageDataArray.length(); + String[] padCodesResult = new String[length]; + + for (int i = 0; i < length; i++) { + JSONObject item = pageDataArray.getJSONObject(i); + if (!item.has("padCode")) { + LogFileUtil.logAndWrite(Log.WARN, "ArmCloudApiClient", "getInstanceListInfo: 返回对象缺少 'padCode' 字段", null); + throw new IOException("返回对象缺少 'padCode' 字段"); + } + padCodesResult[i] = item.getString("padCode"); + } + + return padCodesResult; + + } catch (JSONException e) { + LogFileUtil.logAndWrite(Log.ERROR, "ArmCloudApiClient", "getInstanceListInfo: 响应解析失败", e); + throw new IOException("响应解析失败", e); + } } - } } diff --git a/app/src/main/java/com/example/retention/device/ChangeDeviceInfoUtil.java b/app/src/main/java/com/example/retention/device/ChangeDeviceInfoUtil.java index a39b10a..4355c52 100644 --- a/app/src/main/java/com/example/retention/device/ChangeDeviceInfoUtil.java +++ b/app/src/main/java/com/example/retention/device/ChangeDeviceInfoUtil.java @@ -24,6 +24,7 @@ import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -72,6 +73,8 @@ public class ChangeDeviceInfoUtil { String bigoJson = fetchJsonSafely(buildBigoUrl(country, tag), "bigoJson"); String afJson = fetchJsonSafely(buildAfUrl(country, tag), "afJson"); + LogFileUtil.logAndWrite(android.util.Log.DEBUG, LOG_TAG, "Received bigoJson: " + bigoJson, null); + LogFileUtil.logAndWrite(android.util.Log.DEBUG, LOG_TAG, "Received afJson: " + afJson, null); fallBackToNetworkData(bigoJson, afJson); logDeviceObjects(); @@ -107,37 +110,7 @@ public class ChangeDeviceInfoUtil { } } - public static void getDeviceInfo(String taskId, String androidId) { - if (taskId == null || androidId == null || taskId.isBlank() || androidId.isBlank()) { - LogFileUtil.logAndWrite(android.util.Log.ERROR, LOG_TAG, "Invalid task", null); - return; - } - executorService.submit(() -> { - String response = ""; - try { - response = executeQuerySafely(androidId, taskId); - } catch (Exception e) { - e.printStackTrace(); - } - if (response == null || response.isBlank()) { - LogFileUtil.logAndWrite(android.util.Log.ERROR, LOG_TAG, "Error occurred during query", null); - return; - } - - if (isValidResponse(response)) { - try { - synchronized (ChangeDeviceInfoUtil.class) { // 防止并发访问 - parseAndSetDeviceObjects(response); - } - } catch (JSONException e) { - LogFileUtil.logAndWrite(android.util.Log.ERROR, LOG_TAG, "Error parsing JSON", e); - } - } else { - LogFileUtil.logAndWrite(android.util.Log.ERROR, LOG_TAG, "Error occurred during query", null); - } - }); - } private static String fetchJsonSafely(String url, String logKey) throws IOException { String json = null; @@ -438,7 +411,8 @@ public class ChangeDeviceInfoUtil { // 调用接口更新实例属性 try { - String[] padCodes = client.getDeviceCodes(1, 100, null, null, null, null, null, null, null, null); + String[] padCodes = client.getInstanceListInfo(1, 100, null, null, null, null, null); + LogFileUtil.logAndWrite(Log.DEBUG, "ChangeDeviceInfoUtil", "padCodes: " + Arrays.toString(padCodes), null); String response = client.updateInstanceProperties( padCodes, null, // modemPersistProps diff --git a/app/src/main/java/com/example/retention/task/TaskUtil.java b/app/src/main/java/com/example/retention/task/TaskUtil.java index f31127e..392e04c 100644 --- a/app/src/main/java/com/example/retention/task/TaskUtil.java +++ b/app/src/main/java/com/example/retention/task/TaskUtil.java @@ -139,6 +139,7 @@ public class TaskUtil { Log.d("TaskUtil", "Built HTTP request for device info download"); try (Response response = okHttpClient.newCall(request).execute()) { + LogFileUtil.logAndWrite(android.util.Log.DEBUG, "TaskUtil", "Response : " + response, null); // 检查响应是否成功 if (!response.isSuccessful()) { String errorMessage = "Unexpected response: Code=" + response.code() + @@ -800,4 +801,3 @@ class Payload { AfInfo afDeviceObject; DeviceInfo other; } - diff --git a/app/src/main/jniLibs/arm64-v8a/libnative.so b/app/src/main/jniLibs/arm64-v8a/libnative.so index 57b424b96e178beac309948a8f50a06dd07f6475..967a4181429ae43d9831fb0df1b8bcbdfa361116 100644 GIT binary patch delta 8778 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 delta 8775 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 diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml index b5a1e74..28224a1 100644 --- a/app/src/main/res/xml/network_security_config.xml +++ b/app/src/main/res/xml/network_security_config.xml @@ -13,5 +13,6 @@ 8.217.137.25 47.238.96.231 192.168.30.80 + 39.103.73.250