Javaゲートウェイ
ではいよいよ、プロダクションにコンポーネントを追加していきます。まずは今回のテーマであるMQTTプロトコルでデータを受信するビジネス・サービスを作成します。
IRISはSOAPやxDBCなどさまざまなプロトコルやデータ形式をアダプタと呼ばれるクラスによってサポートしています。しかし、現時点でMQTTアダプタは用意されていません(現在MQTTアダプタを開発中)。
MQTTに限らず、世の中には数多くの標準プロトコルが存在し、また、場合によっては標準ではない通信手順でシステム間連携を行う場面があります。このような状況に対応するため、IRISはJavaゲートウェイという仕組みを開発者の皆さんに提供しています。IRISのビジネス・サービスで定められたメソッドをJavaでプログラムすることによって、ビジネス・サービスの機能を拡張することができます。
Javaコード
MQTTのデータを受信するためのJavaのプログラムは、「IRIS-MQTT/projects/srcs/java/src/com/intersystems/drivedemo/MqttBS.java」にあります。以下では、プログラムのキーとなる部分について紹介します。
ライブラリのインポート
IRISのビジネス・サービスとしての機能を継承するために次のクラスをインポートします。
import com.intersystems.gateway.bh.BusinessService; import com.intersystems.gateway.bh.Production; import com.intersystems.gateway.bh.Production.Severity;
MQTTの通信を行うためにEclipse Pahoのクラスをインポートします。
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; import org.eclipse.paho.client.mqttv3.MqttCallback; import org.eclipse.paho.client.mqttv3.MqttClient; import org.eclipse.paho.client.mqttv3.MqttConnectOptions; import org.eclipse.paho.client.mqttv3.MqttMessage; import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
なお、これらのクラスの実体は、「IRIS-MQTT/projects/srcs/java/lib」にJARファイルとして置いてあります。
クラス定義
クラス定義では、IRISのBusinessServiceインターフェース、PahoのMqttCallbackインターフェースを実装するよう宣言します。
public class MqttBS implements BusinessService, MqttCallback {
SETTINGS変数には、IRISのプロダクションから設定可能な項目を列挙します。
public static final String SETTINGS = "MQTTBroker,MQTTClientName,MQTTTopicRoot,LogFile";
メソッド
ビジネス・サービス起動時に呼び出されるOnInit()メソッドです。
@Override public boolean OnInit(Production prod) throws Exception { // (1) try { production=prod; mqttBroker = production.GetSetting("MQTTBroker"); // (2) mqttClientName = production.GetSetting("MQTTClientName"); mqttTopicRoot = production.GetSetting("MQTTTopicRoot"); // (3) mqttClient = new MqttClient(mqttBroker, mqttClientName); // (4) mqttConnOpts = new MqttConnectOptions(); mqttConnOpts.setCleanSession(true); mqttClient.connect(mqttConnOpts); // (5) production.LogMessage("Successfully connected to MQTT broker: "+mqttBroker,Severity.INFO); String[] myTopics={this.mqttTopicRoot}; mqttClient.subscribe(myTopics); // (6) production.LogMessage("Subscribed to MQTT topic: "+mqttTopicRoot,Severity.TRACE); mqttClient.setCallback(this); // (7) production.LogMessage("Successfully connected to MQTT broker: "+mqttBroker,Severity.INFO); return true; } catch (Exception e) { //System.out.println(e.toString()); production.LogMessage(e.toString(), Severity.ERROR); production.SetStatus(Production.Status.ERROR); } return false; }
- (1)OnInitの引数にはProductionクラスの変数がIRISから渡されます。この変数からプロダクションの設定値などにアクセスできます。
- (2)MQTT Brokerへの接続URLを取得します。この値は、IRISのプロダクションから設定します。
- (3)SubscribeするTopicを指定します。この値は、IRISのプロダクションから設定します。
- (4)MqttClientクラスのインスタンスを作成します。
- (5)MQTT Brokerに接続します。
- (6)MQTT BrokerにSubscribeするTopicを登録します。
- (7)コールバックを処理するインスタンスにthisを指定します。
MQTT Brokerからデータが到着した時に呼び出されるコールバックハンドラ messageArrived()です。
@Override public void messageArrived(String topic, MqttMessage message) throws Exception { // (1) production.LogMessage("java, messageArrived", Severity.TRACE); production.LogMessage("java, topic: "+topic+"; Message:"+message.toString(),Production.Severity.TRACE); Timestamp timestamp = new Timestamp(System.currentTimeMillis()); Instant ts = timestamp.toInstant(); String xmlMessage="<message><type>"+topic+"</type><timestamp>"+ts+"</timestamp><content>"+message.toString()+"</content></message>"; // (2) production.LogMessage("java, xmlMessage:"+xmlMessage,Severity.TRACE); production.SendRequest(xmlMessage); // (3) }
- (1)MQTT Brokerから到着したデータが引数messageに、Topicが引数topicに格納されて呼び出されます。
- (2)受信したデータのTopic、時刻、内容をXMLのタグ付けします。このXMLの形式は、先ほどIRISに読み込ませたXMLスキーマで定義したものに合わせてあります。
- (3)XML形式のデータをリクエストメッセージとして送信します。このリクエストメッセージが「どこに」送られるかなどは後に説明します。
このクラスをコンパイルした.classは、「IRIS-MQTT/projects/srcs/java/lib/IRIS-MQTT-Client.jar」にアーカイブします。