
クラウドの好きな機能をリストとしてまとめると、多くの開発者の”トップ10″リストに通知が入っていることはおそらくないでしょう。通知はどちらかというと”ユーティリティ”機能で、自動車のタイヤのようなもの。必要不可欠で、動かなければイライラさせられますが、順調に動いていれば考えることもほぼありません。 かつて私は通知をこのように捉えていましたが、最近になってオラクルのサービスOracle Notification Serviceを掘り下げるようになってからは変わりました。不思議なことに、このサービスについて学び色々と試すことにワクワクしている自分がいました。Oracle Notification Serviceは、Oracle Cloudの他のサービスと同じく、本当に使いやすく、分かりやすいように実装されています。また、Oracle Cloudの他のサービスだけでなく、外部のツールやサービスとも非常にスムーズに連携します。 ここでは、そんなOracle Notification Serviceについて詳しく見ていきます。
通知は広い概念を含む言葉であるため、その意味を明確にしましょう。アプリケーションで何かが起きたときに、ユーザーに電子メールを送信することがあります。たとえば、ファイルや注文の処理が終わったときに。 これが通知となる可能性があります。また、開発者やDevOpsエンジニアであれば、インフラストラクチャ内で何か変更があったときに、そのことを知りたいと思うのではないでしょうか。たとえば、DBのバックアップが開始した、完了したなど。 これも通知となる可能性があります。ユーザーや開発者が関わらない通知もあります。あるサーバーレス・ファンクションがあって、オブジェクトがObject Storageにアップロードされたときにこのファンクションを実行する必要がある場合に、その操作を通知によって処理できるのです。このように多種多様なアクティビティが”通知”という総称で表されますが、Oracle Notification Serviceは思い付く限りのすべてのシナリオに対処できます。
この記事で取り上げる内容は次のとおりです。
- 通知トピックの作成
- トピックへのサブスクライブ
- 通知を受信するSlackアプリの作成
- Oracle Cloud Infrastructure Java SDKによる通知の送信
- Cloudのイベント経由での通知の自動送信
- サービス・アラーム経由での通知の自動送信
- Zapierによる通知からのGitHubイシューの自動作成
話題は盛りだくさんですので、すぐに1つ目に移りましょう!
通知トピックの作成
通知を使い始めるには、まずトピックを作成する必要があります。Oracle Cloudコンソールから、「Application Integration」→「Notifications」を選択します。

次に、「Create Topic」をクリックします。

トピック名と説明を入力して、「Create Topic」をクリックします。

これで、トピックのサブスクリプションのための準備が整いました。
トピックへのサブスクライブ
通知のサブスクリプションのために利用できるプロトコルはいくつかあります。
- 電子メール
- PagerDuty
- HTTPS(カスタムURL)
- Slack
ヒント:この記事ではサブスクリプションとしての電子メールについては説明しませんが、電子メールのサブスクリプションを利用すれば、携帯電話の“非公開の組込み”電子メール・アドレスを使ってSMS通知を受け取ることができます。 ほとんどの通信会社でこの機能がサポートされています。便利な機能ですので、ぜひ試してみてください。
このブログ記事では、これらのプロトコルの一部について見ていきます。まずはSlackです。最初に、新しく作成したトピックをトピック・リストから選択します。

「Create Subscription」を作成します。

プロトコルとして「Slack」を選択します。このSlackサブスクリプションにはWebフックURLが必要になるため、このウィンドウを開いたままこのブログ記事の次のセクションに移り、新しいSlackアプリケーションを作成してWebフックURLを取得してください。

通知を受信するSlackアプリの作成
通知をSlackチャネルにパブリッシュするには、Slackアプリケーションを作成する必要があります。 まず、Slackを開いて「Create an App」をクリックし、アプリの名前を指定し、アプリを作成するワークスペースを選択して、「Create App」をクリックします。

次に、「Incoming Webhooks」をクリックします。

Webフックはデフォルトで無効であるため、有効にします。

「Add New Webhook to Workspace」をクリックします。

ワークスペースにアクセスするための権限を確認し、ポスト先のチャネルを選択して、「Allow」をクリックします。

これで新しく作成したWebフックURLを取得できます。このURLは少し後の手順で必要になります。

通知のポスト先のSlackチャネルを開き、歯車アイコンのメニューから「Add an app」をクリックします。

または、チャネル内で直接「Add an app」をクリックします。

新しいアプリを検索し、選択します。

チャネル内で確認メッセージが表示されます。

コンソールに戻り、Slack WebフックURLを貼り付けてサブスクリプション・ダイアログの入力を完了します。

この時点で、サブスクリプション確認用メッセージがこのSlackチャネルにポストされます。

このメッセージ内のリンクをクリックして、サブスクリプションを確認します。

次に、このSlackサブスクリプションをテストします。Oracle Cloudコンソールのトピック詳細ページに戻り、「Publish Message」をクリックします。

簡単なメッセージを入力し、「Publish」をクリックします。

Slackチャネルを開き、そのメッセージがポストされたことを確認します。

これで、Oracle Notification ServiceのトピックにサブスクライブできるSlackアプリの作成が完了しました。
Oracle Cloud Infrastructure Java SDKによる通知の送信
この記事ではすでに、かなり多くのことを学びました。通知トピックを設定し、そのトピックにサブスクライブし、トピックから通知を受信するためのカスタムのSlackアプリを作成し、簡単なテスト・メッセージをパブリッシュしました。しかし、すでに説明したように、アプリケーションからトピックやサブスクライバに通知を送信する必要があることも多いため、ここではトピックにメッセージをパブリッシュする小さなJavaアプリケーションについて見ていきます。トピック詳細ページからトピックのOCIDを取得する必要があります。このOCIDをコピーして、いつでも使える状態にします。
このデモの実行に必要なコード全体をGitHubで公開していますので、後でご自由にこのリポジトリを確認してください。 私はGradleが好きなので、まずはbuild.gradleファイルを作成して、Oracle Cloud Infrastructure Java SDKを依存先として含めます。
| plugins { | |
| id ‘java‘ | |
| id ‘application‘ | |
| } | |
| group ‘codes.recursive‘ | |
| version ‘0.1-SNAPSHOT‘ | |
| sourceCompatibility = 1.8 | |
| repositories { | |
| mavenCentral() | |
| } | |
| application { | |
| mainClassName = ‘codes.recursive.OnsSendExample‘ | |
| } | |
| dependencies { | |
| compile group: ‘com.oracle.oci.sdk‘, name: ‘oci-java-sdk-full‘, version:‘1.9.0‘ | |
| testCompile group: ‘junit‘, name: ‘junit‘, version:‘4.12‘ | |
| } | |
| tasks.withType(JavaExec) { | |
| systemProperties System.properties | |
| } |
IDEでRun/Debugプロファイルを作成し、Oracle Notification ServiceのトピックOCIDを環境変数として設定します。

Ons.javaというクラスを作成します。このクラスを、SDKクライアントを呼び出してメッセージをパブリッシュするために利用します。このクラスには、引数としてtitleとmessageを受け取るsendNotfication()というメソッドが1つ含まれます。認証プロバイダを作成し、利用するプロファイルの名前を渡します(この例ではパスを指定していないため、デフォルトのOracle Cloud Infrastructure設定ファイルの場所[/.oci/config]が設定ファイル自体として利用されます)。次に、NotificationDataPlaneClientとMessageDetailsオブジェクトを作成します。このオブジェクトにタイトル(title)とメッセージ(message)が格納されます。 その後、MessageDetailsインスタンスを格納したPublishMessageRequestを作成し、最後にクライアント(client)にPublishMessageRequestを渡すことでメッセージをパブリッシュします。 この説明からは面倒で複雑だと感じられるかもしれませんが、以下のコードを見れば簡単だとお分かりいただけるはずです。
| package codes.recursive; | |
| import com.oracle.bmc.auth.ConfigFileAuthenticationDetailsProvider; | |
| import com.oracle.bmc.ons.NotificationDataPlaneClient; | |
| import com.oracle.bmc.ons.model.MessageDetails; | |
| import com.oracle.bmc.ons.requests.PublishMessageRequest; | |
| public class Ons { | |
| public void sendNotification(String title, String message) throws Exception { | |
| String topicId = System.getenv(“TOPIC_ID“); | |
| if( topicId == null ) { | |
| throw new Exception(“Please set a TOPIC_ID environment variable!“); | |
| } | |
| ConfigFileAuthenticationDetailsProvider provider = new ConfigFileAuthenticationDetailsProvider(“DEFAULT“); | |
| NotificationDataPlaneClient client = NotificationDataPlaneClient.builder().region(“us-phoenix-1“) | |
| .build(provider); | |
| MessageDetails messageDetails = MessageDetails.builder().title(title).body(message).build(); | |
| PublishMessageRequest publishMessageRequest = PublishMessageRequest.builder() | |
| .messageDetails( messageDetails ) | |
| .topicId(topicId) | |
| .build(); | |
| client.publishMessage( publishMessageRequest ); | |
| } | |
| } |
次に、OnsSendExample.javaという必要最小限のメイン・クラスを作成し、このクラス内でOnsクラスのインスタンスを作成して通知を送信します。
| package codes.recursive; | |
| import java.util.Date; | |
| public class OnsSendExample { | |
| public static void main(String… args) throws Exception { | |
| Ons ons = new Ons(); | |
| ons.sendNotification( | |
| “Test from Java“, | |
| “This is a test notification sent by the Java SDK at “ + new Date().toString() | |
| ); | |
| } | |
| } | |
Slackチャネルをチェックして、配信されたことを確認できます。

Cloudのイベント経由での通知の自動送信
Cloudのイベントについては以前にこのブログで取り上げましたが、当時の背景情報は異なりますし、学び直すことは良いことですので、Cloudのイベント経由での通知の送信についても詳しく見ていきましょう。
そもそも、Cloudのイベントとはどういったものでしょうか。 多くのサービスはOracle Cloudで発行されるイベントであり、それらのイベントはCNCF Cloud Event仕様に従って構造化されたメッセージです。作成、読取り、更新、または削除(CRUD)の操作、リソースのライフサイクルの状態変更、あるいはリソースに影響を及ぼすシステム・イベントなどがイベントに該当します。 たとえば、バックアップの完了時または失敗時、あるいは Object Storage バケット内のファイルの追加時、更新時、または削除時にイベントが発行されます。
以下のように、Cloudのイベントを生成するさまざまなOCIサービスが存在します。
- ブロック・ボリューム
- コンピュート
- データベース
- ネットワーク
- 通知
- Object Storage
サービスごとに使いやすいイベント・タイプが多数用意されているため、インフラストラクチャを監視するための大きな助けになります。例として、自律型データベースのイベント・タイプを見てみましょう。
- バックアップ作成開始(Create Backup Begin)
- バックアップ作成終了(Create Backup End)
- インスタンス作成開始(Create Instance Begin)
- インスタンス作成終了(Create Instance End)
- リストア開始(Restore Begin)
- リストア終了(Restore End)
さらに、ブロードキャストされるイベント・タイプ一式が存在するのは自律型データベースだけではありません。以下のように、Oracle Cloudのありとあらゆるデータベース関連要素にそれ独自のイベント・タイプが用意されています。
- 自律型データベース
- 自律型コンテナ・データベース
- 自律型Exadataインフラストラクチャ・インスタンス
- Exadataインフラストラクチャ
- VMクラスタ・ネットワーク
- VMクラスタ
- バックアップ先
- データベース・ノード
- データベース・ホーム
- データベース
Cloudのイベントを利用するには、ルールを作成します。ルールには、ルールがトリガーされる基になる特定のリソースや属性を指定するためのフィルタを含めることができます。さらに、ルールの条件が満たされたときに実行すべきアクションも作成します。 現時点では、ファンクション(Oracle Functionのサーバーレス・ファンクションを呼び出す)、ストリーミング(Oracle Streaming Serviceのストリームに対するメッセージを生成する)、通知(Oracle Notification Serviceトピックにイベントをパブリッシュする)の3つのタイプのアクションから選択できます。この3つ目のアクションについて、これから説明していきます。それでは、ルールを作成してみましょう。
Oracle Cloudコンソールのサイドバー・メニューで、「Application Integration」→「Events Service」を選択します。

次に、ルール・リストのページで、「Create Rule」を作成します。

名前と説明を入力します。

次に、このルールにフィルタを追加し、Object Storageサービスのイベント、特にObject Createイベントのみに制限するようにします。さらに、特定のバケットのみにフィルタを制限します。

次に、ルールがトリガーされたときに実行するアクションを定義します。この例では、Oracle Notification Serviceトピックを呼び出しましょう。

この時点でルールを保存してテストできます。テストするには、オブジェクトをObject Storageバケットにアップロードします。Slackチャネルにまったく新しいメッセージが送信されます。このメッセージは先ほど確認したものとは少し異なり、Cloudのイベント全体がJSON形式の文字列で表されていますが、このメッセージには、この通知からアクションを実行する必要がある場合に利用できる有用な情報が大量に含まれています。

サービス・アラーム経由での通知の自動送信
アラームはOracle Cloud内のリソースやインフラストラクチャを監視し続けるための非常に優れた手段です。アラームの作成は本当に簡単で、アラームが指定したしきい値に達すると、Oracle Notification Serviceに通知をパブリッシュできます。 ここでは、Object Storageバケットが1分に10回を超えるGetリクエストを受信した場合に通知をパブリッシュするアラームを作成してみましょう。 ただし、これはサンプルとしては不自然なものになっています。多くのサービスには便利なメトリックが用意されていて、それらを利用すればMonitoringサービスで継続的に監視できるのですから。 それでは、デモのアラームを作成してテストしてみます。コンソールのサイドバー・メニューで、「Monitoring」→「Alarm Definitions」を選択します。

次に、「Create Alarm」をクリックします。

名前を付け、重大性を選択し、アラーム・メッセージの本文を定義します。

次に、このアラーム用に評価されるメトリックを定義します。名前空間’oci_objectstorage‘を選択し(他にも多数のオプションがあります)、メトリックに’GetRequests‘を選択し、時間隔として1分、統計として’count’を選択します。ディメンション名として’resourceDisplayName’を追加し、特定のバケットをディメンション値として選択して、特定のObject Storageバケットだけになるようにこのメトリックをフィルタします。さらに、トリガー・ルールを’greater than’、値を1、トリガー間隔を1分とします。 これらの指定によって、1分間で1つを超えるGetリクエストが存在する場合にアラームがトリガーされます。

最後に、下にスクロールして通知の詳細を指定し、「Save alarm」をクリックします。

テストするには、指定したバケット内に保存されている画像に対して、何回か’GET’リクエストを実行します。最初のリクエストの後にアラームがトリガーされ、先ほどと同じようにSlackチャネルにメッセージがポストされます。

Zapierによる通知からのGitHubイシューの自動作成
記事の最後に、外部との統合の例を示そうと思っていましたが、今回は上記の例よりも少し”現実に近い”アプリケーションを取り上げることにします。この例では、Zapierによって作成されるHTTPS(カスタムURL)エンドポイントを使ってトピックにサブスクリプションを追加します。Zapierは、定められたトリガーに基づいて定められたアクションを実行する”Zap”を作成するためのプラットフォームであり、その考え方はIFTTT(”if this then that”)に似ています。 ここでは、Zapier Webフックをトリガー(”これが起きたとき”というアクション)として作成し、GitHubを宛先として利用します(”これをする”というアクション)。ここまでは大丈夫でしょうか?では、まず”Zap”を作成しましょう。’アプリ’として「Webhooks by Zapier」を選択し、トリガー・イベントとして「Catch Raw Hook」を選択します。

この設定によって、カスタムのWebフックURLが表示されます。この情報は後で必要になります。

次に、このZapのステップ2で、’アプリ’として「GitHub」を選択し、アクション・イベントとして「Create Issue」を選択します。

詳細情報として、プロジェクトのリポジトリ、イシューのタイトル、イシューの本文(この例ではOracle Notification Serviceからのメッセージ本文そのもの)を入力します。

保存し、この新しいWebフック用のサブスクリプションを作成します。

作成された新しいGitHubイシューを表示して、このサブスクリプションの動作を確認します。

有効にし、Oracle Cloudコンソールからメッセージをパブリッシュしてテストします。

CloudのイベントのJSONを解析することもできます。そのためには、一時的にZapのJavaScriptコードを利用して、その後GitHubイシューを作成して、整形されたチケットを生成します(さらに、特定のイベントタイプに絞り込むためのフィルタを追加するといったことも可能です)。



Zapierでは他にも、Jiraイシューの作成、SMSアラートの送信、Twitter統合など、実に多くの追加の統合機能を利用できます。
まとめ
私が通知を使い始めた当初はやや面白みがないと感じていました。しかしすぐに、通知が開発を容易にしてアプリケーションをよりインテリジェントにする大きな可能性を秘めていると分かりました。この記事の情報量が多いことは承知しており、 おそらく2~3つの記事に分割できたでしょうが、このような形でまとめたまま公開すべきものだと感じた次第です。この記事をぜひブックマークして、今後の参考資料としてお役立てください。ご質問については、以下のコメント欄からどうぞ。
お知らせ: この記事で使ったコードはGitHubでも公開されています。ぜひご覧ください。 https://github.com/recursivecodes/ons-demo
Photo by AbsolutVision on Unsplash
※本記事は、Todd Sharp (Developer Advocate)による”Complete Developers Guide To The Oracle Notification Service“を翻訳したものです。

