全部產品
Search
文件中心

IoT Platform:執行個體遷移服務端修改樣本

更新時間:Jun 30, 2024

執行個體遷移後相關業務的雲端API運行需要切換到目標企業版執行個體下,因此您需開發更新資料庫中裝置所屬執行個體ID資訊的方法,以及在調用雲端API控制裝置服務時,傳入更新後企業版執行個體ID的方法。本文以Java語言的開發環境為例,介紹執行個體遷移相關業務系統中服務端的修改樣本。

背景資訊

執行個體遷移的詳細說明,請參見使用前必讀

訂閱執行個體遷移資料的方法,請參見設定資料流轉規則

開發環境說明

開發環境如下:

範例程式碼說明

功能

說明

更新裝置資料

解析公用執行個體通過規則引擎訂閱的執行個體遷移訊息:解析遷移成功的裝置流轉訊息,根據裝置資訊更新資料庫儲存的執行個體ID資訊。

控制裝置服務

修改控制裝置相關業務的介面調用方法: 調用雲端介面時,先查詢資料庫表中執行個體ID資訊(企業版執行個體ID),然後設定介面請求參數IotInstanceId為該企業版執行個體ID,最後調用介面。

更新裝置資料的範例程式碼

您需依賴AMQP用戶端接入的SDK,開發更新裝置資料的方法。AMQP用戶端接入樣本,請參見Java SDK接入樣本

更新處理執行個體遷移訊息的方法:processMessage方法,替換為如下代碼。其中updateDeviceInstanceId(productKey, deviceName, targetInstanceId)recoverDeviceInstanceId(productKey, deviceName)是實現資料庫更新資料的方法,需開發人員根據實際情境自行完成開發。

private static void processMessage(Message message) {
        try {
            byte[] body = message.getBody(byte[].class);
            String content = new String(body);
            String topic = message.getStringProperty("topic");
            String messageId = message.getStringProperty("messageId");
            logger.info("receive message"
                + ",\n topic = " + topic
                + ",\n messageId = " + messageId
                + ",\n content = " + content);

            if (null == content) {
                logger.error("content is null");
            }

            JSONObject object = JSON.parseObject(content);
            String status = object.getString("status");

            // 更新遷移成功的裝置執行個體ID。
            String targetInstanceId = object.getString("targetInstance");

            // 處理遷移成功的裝置, 更新為目標企業執行個體ID。
            if (StringUtils.equals(status, "GRAY_EXECUTING") || StringUtils.equals(status, "ALL_EXECUTING")) {
                JSONArray successDevices = object.getJSONArray("successDevices");

                if (successDevices == null) {
                    return;
                }

                for (int i = 0; i < successDevices.size(); i++) {
                    JSONObject device = successDevices.getJSONObject(i);
                    if (null == device) {
                        return;
                    }

                    String deviceName = device.getString("deviceName");
                    String productKey = device.getString("productKey");

                    // todo:根據productKey和deviceName, 按照target更新資料庫中遷移成功的裝置執行個體ID。
                    // updateDeviceInstanceId(productKey, deviceName, targetInstanceId)


                }
            }

            // 處理復原成功的裝置,恢複為原有執行個體ID。
            if (StringUtils.equals("status", "ROLL_BACK_EXECUTING")) {
                JSONArray successDevices = object.getJSONArray("successDevices");
                if (successDevices == null) {
                    return;
                }

                for (int i = 0; i < successDevices.size(); i++) {
                    JSONObject device = successDevices.getJSONObject(i);
                    if (null == device) {
                        return;
                    }

                    String deviceName = device.getString("deviceName");
                    String productKey = device.getString("productKey");

                    // todo:根據productKey和deviceName, 恢複資料庫中的instanceId. 恢複策略具體需要區分業務情境。
                    // 1、原有公用執行個體調用業務沒有存執行個體ID, 恢複執行個體ID為null。
                    // 2、原有公用執行個體調用存了執行個體ID特定值, 恢複執行個體ID為原有預設值。
                    // recoverDeviceInstanceId(productKey, deviceName)
                }
            }
        } catch (Exception e) {
            logger.error("processMessage occurs error ", e);
        }
    }

控制裝置服務的範例程式碼

您需依賴物聯網平台雲端SDK,開發調用裝置相關業務API的方法。雲端SDK使用樣本,請參見Java SDK使用說明

配置依賴的介面調用方法:以Pub介面為例,如下代碼新增調用介面方法pub(client, productKey, deviceName)。其中getInstanceId(productKey, deviceName)方法實現邏輯,需開發人員根據實際情境自行完成開發。

  public static void main(String[] args) {
        String accessKey = "${accessKey}";
        String accessSecret = "${accessSecret}";
        String productKey = "${productKey}";
        String deviceName = "${deviceName}";
        IClientProfile profile = DefaultProfile.getProfile("cn-shanghai", accessKey, accessSecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);

        pub(client, productKey, deviceName);
    }

    private static void pub(DefaultAcsClient client, String productKey, String deviceName) {
        PubRequest request = new PubRequest();
        //從資料庫中擷取執行個體ID。
        String instanceId = getInstanceId(productKey, deviceName);

        //如果執行個體ID不為空白,傳參設定執行個體ID。注意只有企業執行個體需要傳入此參數,公用執行個體無需傳入此參數。
        if (!StringUtils.isEmpty(instanceId)) {
            request.setIotInstanceId(instanceId);
        }

        request.setProductKey("${productKey}");
        request.setMessageContent(Base64.encodeBase64String("hello world".getBytes()));
        request.setTopicFullName("/${productKey}/${deviceName}/user/get");
        request.setQos(0); //目前支援QoS0和QoS1。
        try {
            PubResponse response = client.getAcsResponse(request);
            System.out.println(response.getSuccess());
            System.out.println(response.getCode());
            System.out.println(response.getErrorMessage());
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            e.printStackTrace();
        }
    }

    /**
     * 從資料庫中擷取執行個體ID。
     *
     * @param productKey
     * @param deviceName
     * @return
     */
    private static String getInstanceId(String productKey, String deviceName) {
        String instanceId = "";
        // todo:按照 productKey和deviceName從資料庫中查詢梳理資訊。
        // instanceId = query(productKey, deviceName);

        return instanceId;
    }