インスタンス移行後、関連サービスのクラウド API 呼び出しを移行先の Enterprise Edition インスタンスにリダイレクトする必要があります。そのためには、データベース内のデバイスインスタンス ID を更新し、デバイスサービスを制御するクラウド API を呼び出す際に更新後の Enterprise Edition インスタンス ID を渡すメソッドを開発する必要があります。この例では、 Java 開発環境を使用します。
背景情報
インスタンスの移行については、「使用上の注意事項」をご参照ください。
インスタンス移行データをサブスクライブするには、「データ転送ルールの設定」をご参照ください。
開発環境
開発環境には以下が必要です。
-
JDK バージョン: JDK 8 以降
-
統合開発環境 (IDE): IntelliJ IDEA Community Edition
サンプルコードの説明
|
機能 |
説明 |
|
デバイスデータの更新 |
ルールエンジンを介してパブリックインスタンスからサブスクライブしたインスタンス移行メッセージを解析します。次に、正常に移行されたデバイスのデータ転送メッセージを処理し、デバイス情報に基づいてデータベース内のインスタンス ID を更新します。 |
|
デバイスサービスの制御 |
デバイス制御サービスの API 呼び出しメソッドを変更します。クラウド API を呼び出す際、データベーステーブルから Enterprise Edition インスタンス ID を照会し、 IotInstanceId リクエストパラメータをこのインスタンス ID に設定してから、API を呼び出します。 |
デバイスデータ更新のサンプルコード
デバイスデータを更新するメソッドは、 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 を移行先の Enterprise Edition インスタンス 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、targetInstanceId に基づいて、データベース内の正常に移行されたデバイスのインスタンス 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);
}
}
デバイスサービス制御のサンプルコード
デバイス関連のビジネス API を呼び出すメソッドは、 IoT Platform クラウド SDK に依存します。詳細については、「Java SDK 使用上の注意事項」をご参照ください。
次のコードでは、 Pub API を例に、 pub(client, productKey, deviceName) API 呼び出しメソッドを追加します。 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 を設定します。このパラメータは Enterprise Edition インスタンスのみに必要であることに注意してください。パブリックインスタンスには不要です。
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); // QoS 0 と QoS 1 がサポートされています。
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;
}