Oracle CloudのDevOpsサービスを使ってみようとしたところ、プロジェクトの作成には通知サービスのトピックが必要でした。通知のトピックは簡単に作れますが、それだけだと面白味がないので、作成したトピックにSlackのサブスクリプションを作成し、APEXアプリケーションからメッセージを送信(英語でPublishなので公開と翻訳されています)してみました。
以下のような動作になります。
https://blogs.oracle.com/otnjp/post/en_article_08
APEXアプリケーションからSlackに通知する方法は、以前にこちらの記事に記載しています。今回もIncoming Webhookを使用します。
気になる費用ですが、Oracle Cloud Infrastructure NotificationsサービスのFAQより確認しました。
Notificationsでは、Oracle Cloud Infrastructureのお客様が無償で開始できるように無償枠が導入されています。お客様は、1か月あたり100万件のHTTPSエンドポイントへのメッセージと1,000件のメール・メッセージを無償で配信することができます。
メール・メッセージはともかく、人によるアプリケーションの操作でHTTPSの無償枠を超えることはなさそうです。
では、以下よりアプリケーションを作成するために実施した作業を紹介します。
SlackチャンネルとWebhookの作成
OCIのトピックのサブスクリプションとして作成する、SlackのIncoming Webhookを取得します。
最初にチャンネルを作成します。
Slackのクライアントより、チャンネルを作成するを実行します。
チャンネルの名前と説明を入力し、作成を実行します。今回はチャンネルの名前をtest-oci-notifとしました。
チャンネル#test-oci-notifが作成されます。チャンネル名をクリックして、チャンネルの詳細を開きます。
インテグレーションのタブを開き、アプリを追加するを実行します。
検索ボックスにIncoming Webhooksと入力します。Incoming WebhooksがAppディレクトリに現れるので、インストールを実行します。
ブラウザにIncoming Webhooksの説明が表示されます。Incoming Webhooksを使ったインテグレーションは非推奨と記述されています。現在の推奨はchat.postMessageのようですが、Oracle Cloudのサブスクリプションとして登録できるのは、Incoming Webhooksのなので、Slackに追加を実行します。
チャンネルとして先ほど作成した#test-oci-notifを選択し、Incoming Webhookインテグレーションの追加を実行します。
チャンネル#test-oci-notifのIncoming Webhookが作成されました。
画面下にIncoming Webhookに関する設定があります。Webhook URLをコピーし、後で利用できるようにどこかに記録しておきます。説明ラベルや名前、アイコンなどをカスタマイズして、設定を保存します。
以上で、SlackのIncoming Webhookの準備は完了です。
通知サービスのトピックとサブスクリプションの作成
OCIコンソールの開発者サービスに含まれる、アプリケーション統合の通知を開きます。
最初にトピックを作成します。Free Tierアカウントを使っていることもあり、コンパートメントは作成せず、ルート・コンパートメントに作成します。
トピックの作成を実行します。
作成をクリックします。
トピックはすぐに作成されます。作成されたトピックtest-oci-notifを開き、サブスクリプションを作成します。
画面右にドロワーが開きます。プロトコルとしてSlackを選択し、URLに先ほど作成したWebhook URLを入力します。
作成をクリックします。
Slackのチャンネルに、以下のようなサブスクリプションの確認を求める通知が送信されます。URLのリンクをクリックし、サブスクリプションの作成を確認します。
以上で通知サービスのトピックとサブスクリプションの作成が完了しました。メッセージの送信にトピックのOCIDを使用するため、OCIDのコピーを取得しておきます。
メッセージを送信するユーザーの作成
トピックへメッセージを送信する権限を持ったユーザーを作成します。
OCIコンソールよりアイデンティティとセキュリティに含まれるユーザーを開きます。
ユーザーの作成を実行します。
作成を実行します。
ユーザーnotification-botが作成されたら、リソースよりAPIキーを開きます。
APIキーの追加を実行します。
APIキーの追加を行うダイアログが開きます。APIキー・ペアの生成を選択し、秘密キーのダウンロードを実行します。ダウンロードされた秘密キーが含まれるファイル名は、忘れないようにしてください。
その後、追加をクリックします。
追加をクリックすると構成ファイルがプレビューされます。この情報を使ってデータベースにクリデンシャルを作成します。コピーをして、後で参照できるように保存しておきます。
情報を保存したら、閉じるをクリックします。
必ずしも必要な作業ではありませんが、ユーザー機能の編集をしておきます。
ユーザー機能のAPIキーだけチェックを残し、他のチェックをすべて外します。
変更の保存を実行します。
アイデンティティのグループを開き、グループの作成を実行します。
画面右にドロワーが開きます。
作成するグループの名前はnotif-bot-group、説明に通知する権限を持つグループと記述します。
作成を実行します。
リソースのグループ・メンバーより、ユーザーをグループに追加を実行し、先ほど作成したユーザーnotificatiuon-botをグループに追加します。
ダイアログが開くので、ユーザーとしてnotification-botを選択し、追加をクリックします。
以上で、グループnotif-bot-groupに、ユーザーnotification-botが追加されました。
グループの準備は以上で完了です。
最後にポリシーを定義します。
アイデンティティのポリシーを開きます。ポリシーの作成を実行します。
allow group notif-bot-group to use ons-topic in tenancy
以上を設定を行い、作成をクリックします。
ポリシーAllowNotificationPolicyが作成されました。
以上で、トピックへメッセージを送信する権限を持ったユーザーnotification-botの作成が完了しました。
APEXアプリケーションを作成する前準備
APEXアプリケーションでは、通知に関するPL/SQL SDKが実装されているパッケージDBMS_CLOUD_OCI_ONS_NOTIFICATION_DATA_PLANEを使用します。関係するタイプとパッケージDBMS_CLOUDを含めて、APEXのワークスペース・スキーマで使えるように、実行権限を与えます。
データベース・アクションのSQLより、以下のコマンドを実行します。
grant execute on dbms_cloud_oci_ons_notification_data_plane_publish_message_response_t to apexdev;
grant execute on dbms_cloud_oci_ons_message_details_t to apexdev;
grant execute on DBMS_CLOUD_OCI_ONS_NOTIFICATION_DATA_PLANE to apexdev;
grant execute on dbms_cloud to apexdev;
APIの呼び出しに使用するクリデンシャルを作成します。
APEXのSQLワークショップのSQLコマンドを開きます。
DBMS_CLOUD.CREATE_CREDENTIALを実行します。クリデンシャル名はMY_NOTIF_CREDとします。
declare
C_RSA_KEY constant varchar2(4000) := q'~
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC4CJLnF7vcPADr
s/loy/A/sT6H+j2pZNAQkBU48WpMeRgHqkZ7TNyCzn1+q3Vj+drO9lPT1SNVbsb9
ダウンロードした秘密キーのファイルの内容
4+6RJWJS0i7Oai6ZMfxnCV3vzzbXxs1hluaD2p3u6JQosDUzQ/qatt+PVWVldoJz
HPWM0pRKD8zT3IsL41+VEweN
-----END PRIVATE KEY-----
~';
l_oneline_key varchar2(4000);
begin
-- 一行にする。
l_oneline_key := regexp_replace(
C_RSA_KEY
,'(-+((BEGIN|END) (RSA )?(PUBLIC|PRIVATE) KEY)-+\s?|\s)'
, '');
dbms_cloud.create_credential(
credential_name => 'MY_NOTIF_CRED'
, user_ocid => '構成ファイルのuser=で指定されているOCID'
, tenancy_ocid => '構成ファイルのtenancy=で指定されているOCID'
, private_key => l_oneline_key
, fingerprint => '構成ファイルのfingerprint=で指定されている値'
);
end;
/
引数のuser_ocid、tenancy_ocid、fingerprintはAPIキーを登録したときに表示された、構成ファイルに記載があります。秘密キーのデータは内容を一行にして、private_keyに与えます。作成したクリデンシャルは、ビューUSER_CREDENTIALSより確認できます。
select credential_name, enabled from user_credentials
APEXアプリケーションの作成
通知を送信するAPEXアプリケーションを作成します。
アプリケーション作成ウィザードを起動し、空のアプリケーションを作成します。名前は通知のテストとします。
アプリケーションの作成を実行します。
アプリケーションが作成されたら、ホーム・ページをページ・デザイナで開きます。
通知に使用するページ・アイテムやボタンを配置するリージョンを作成します。
Bodyにリージョンを作成し、識別のタイトルを通知、タイプは静的コンテンツとします。
通知を送信するファンクションDBMS_CLOUD_OCI_ONS_NOTIFICATION_DATA_PLANE.PUBLISH_MESSAGEの引数となるページ・アイテムを作成します。
P1_REGIONにリージョン、P1_TOPICに宛先となるトピックのOCID、P1_TITLEに通知のタイトル、P1_BODYに通知の本文を設定します。それに加えて送信ボタンを作成します。
ページ・アイテムP1_REGIONの識別のタイプはテキスト・フィールド、ラベルはリージョンとします。
ページ・アイテムP1_TOPICの識別のタイプはテキスト・フィールド、ラベルはトピックとします。
ページ・アイテムP1_TITLEの識別のタイプはテキスト・フィールド、ラベルはタイトルとします。
ページ・アイテムP1_BODYの識別のタイプはテキスト領域、ラベルは本文とします。
最後にボタンを作成します。
作成したボタンの識別のボタン名はB_SUBMIT、ラベルは送信とします。
画面上へのコンポーネントの配置は以上です。
続いて、ボタン送信を押したときに実行するプロセスを作成します。左ペインでプロセス・ビューを開き、プロセスを作成します。
作成したプロセスの識別の名前を通知の送信とします。タイプとしてコードの実行を選択します。ソースのPL/SQLコードとして、以下を記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare | |
l_message dbms_cloud_oci_ons_message_details_t; | |
l_response dbms_cloud_oci_ons_notification_data_plane_publish_message_response_t; | |
begin | |
l_message := dbms_cloud_oci_ons_message_details_t(); | |
l_message.title := :P1_TITLE; | |
l_message.body := :P1_BODY; | |
l_response := DBMS_CLOUD_OCI_ONS_NOTIFICATION_DATA_PLANE.publish_message( | |
credential_name => 'MY_NOTIF_CRED' | |
, topic_id => :P1_TOPIC | |
, region => :P1_REGION | |
, message_details => l_message | |
); | |
end; |
サーバー側の条件のボタン押下時として、B_SUBMITを選択します。
以上で、OCIの通知にメッセージを送信するAPEXアプリケーションは完成です。
アプリケーションを実行すると、記事の先頭のGIF動画のように動作します。
Slackに通知するだけであれば、APEXから直接Slackを呼び出した方がメッセージのフォーマットもできますし、Incoming Webhookではなく、chat.postMessageによるインテグレーションも可能です。そのため、APEXからOCIの通知経由でSlackにメッセージを送信するケースはあまりないと思います。どちらかというと、APEXアプリケーションをOCIの監視フレームワークに組み込む際に活用できる気がします。
今回作成したアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/oci-notification-app.sql
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完