[CentOS6][SOS JobScheduler] AmazonSNS をトリガにしてジョブを実行する


Create: 2015/07/04
LastUpdate: 2015/07/05
[ メニューに戻る ]

AWSのCloudWatchは、アラーム発生時にAmazonSNSを使用してHTTPでメッセージを送信することができます。
そこで、AmazonSNSのHTTPメッセージを JobScheduler のWebServiceで受信して、ジョブを実行できるか試してみました。
試したときの環境は下図のとおり。


JobSchedulerの WebService は UTF-8 のリクエストを処理できないので、Apacheのリバースプロキシで、無理やり、リクエストヘッダの Content-Type を書き換えます。
ちなみに、今年(2015年)の年末リリース予定の JobScheduler 1.11 が UTF-8 に対応するそうです。詳しくは、下記URLを参照してください。
AmazonSNSは、HTTPメッセージの送信先(URL)を登録すると、登録したURLに「受信確認メッセージ」を送信します。この受信確認メッセージに記載されたURLをクリックしないと、HTTPメッセージは通知できません。
自分でURLを叩いてもいいのですが、受信確認もJobSchedulerで行うことにします。AmazonSNSの詳細は、下記URLを参照してください。
JobSchedulerには、AWSから送信されるHTTPリクエストを解析する「リクエスト解析ジョブ」と、”受信確認メッセージ”を処理する「受信確認ジョブ」、”通知メッセージ”を処理する「受信処理ジョブ」の3種類を用意しました。
結果としては、SNSの通知をトリガにしてジョブを実行することができたので、試した手順を以下に紹介します。

1.リバースプロキシの設定


今回、Apache と JobScheduler は、同じサーバにインストールしています。
Apacheに、リバースプロキシの設定をして、Apacheを介して、AWSとJobSchedulerが通信するようにします。
/etc/httpd/conf/httpd.conf に下記内容を追加します。
Listen 8080
<VirtualHost *:8080>
    ServerName www.example1.com
    ProxyPass / http://localhost:4444/
    ProxyPassReverse / http://localhost:4444/
    AddDefaultCharset ISO-8859-1
    RequestHeader unset Content-Type
    RequestHeader append Content-Type text/plain
</VirtualHost>
リバースプロキシのポート番号は、8080 、ポート番号 4444 は、JobScheduler です。
AWSが送信するリクエストヘッダは、"Content-Type: text/plain; charset=UTF-8" なので、一旦、Content-Type を削除したあと、charset なしの Content-Type を設定して、JobScheduler に渡すようにしています。

2.JobSchedulerの設定


JobSchedulerに、WebService の設定をし、下記URLでJobCainを実行できるようにします。
  • http://blue21.ddo.jp:8080/ws_test1
scheduler.xml に以下の設定を追加します。
<http_server>
  <web_service name="test" job_chain="/ws/ws_test1" url_path="/ws_test1" />
</http_server>
これで、上記URLで、config/live/ws ディレクトリの ws_test1.job_chain.xml という JobChain が実行できるようになります。
ws_test1.job_chain.xml の内容は以下のとおり。
job001でリクエスト内容を解析し、next_state を変更してj、ジョブの流れを制御します。受信確認の場合は、job001⇒job100、通知であれば、job001⇒job200 と流れるようにします。
<job_chain >
  <job_chain_node state="001" job="job001" next_state="100" error_state="999" />
  <job_chain_node state="100" job="job100" next_state="999" error_state="999" />
  <job_chain_node state="200" job="job200" next_state="999" error_state="999" />
  <job_chain_node state="999"/>
</job_chain>
job001 の内容は、以下のとおり。
AWSからは、JSON形式のデータが送信されてきます。TYPEが、"SubscriptionConfirmation" であれば受信確認メッセージになります。
Orderパラメータに、受信確認用のURLを設定して、State を 100 に設定し、job100が実行されるよにします。
通知メッセージであれば、State を 200 に設定して、job200 を実行するようにします。
最後に、AWSヘレスポンスを返します。
<job order="yes">
    <script  language="javascript">
        <![CDATA[
function spooler_process()
{
        var order = spooler_task.order;
        var operation;

        try{
                operation = order.web_service_operation;
        } catch (e){
                spooler_log.info("There is no Web Service operation attached to this order");
                return true;
        }

        // read request
        var request = operation.request;
        spooler_log.info("Webservice Request:\n"+request.string_content);
        var data = eval( '(' + request.string_content + ')' );

        // get url & change state
        if( data.Type == "SubscriptionConfirmation" ) {
            order.params.set_var('url',data.SubscribeURL);
            order.state="100";
        } else {
            order.params.set_var('subject',data.Subject);
            order.params.set_var('message',data.Message);
            order.state="200";
        }

        // send reply
        var response = operation.response;
        response.string_content = "OK";
        response.send();

        return true;
}
        ]]>
    </script>
    <run_time />
</job>
job100の内容は、以下のとおり。
job001でOrderパラメータに設定した受信確認用のURLを入力して、curlコマンドでアクセスします。
<job order="yes">
    <script  language="shell">
        <![CDATA[
echo "START 100"
echo "URL=$SCHEDULER_PARAM_URL"
curl $SCHEDULER_PARAM_URL
        ]]>
    </script>
    <run_time />
</job>
job200の内容は、以下のとおり。
job001でOrderパラメータに設定したSubject、Message を表示します。
<job order="yes">
    <script language="shell">
        <![CDATA[
echo "START 200"
echo "Subject=$SCHEDULER_PARAM_SUBJECT"
echo "Message=$SCHEDULER_PARAM_MESSAGE"
        ]]>
    </script>
    <run_time />
</job>
上記で作成した JobChainは、JOCでは下図のように見れます。


3.Amazon SNSの設定


AmazonSNSに HTTPメッセージの送信先として上記で作成した WebServiceのURLを登録します。
今回は、AmazonSNS に "jobscdl" の名前で Topic を登録しました、赤枠をクリックして、HTTPメッセージの送信先を登録します。


[Create Subscription] をクリックします。


[Endpoint]に JobSchedulerの WebServiceのURLである、"http://blue21.ddo.jp.:8080/ws_test1" を設定します。
[Create Subscription]をクリックすると、受信確認メッセージが送信されます。


受信確認が完了していない場合は、赤枠のように表示されます。


JobSchedulerのジョブが実行されて、受信確認が完了したら、画面を再表示します。
受信確認が完了していれば、下図のように SubscriptionID が表示されます。


JobSheculer の実行結果は下図のとおり。
job001⇒job100の順番でジョブが実行され、AWSから受信したメッセージ内容と、curlコマンドの実行結果(受信確認のレスポンス)が表示されています。


4.HTTPメッセージ送信


受信確認が終了したので、HTTPメッセージを通知してみます。
AmazonSNSで [Publish to topic] をクリックします。


[Subject] と [Message] を入力します。
[Publish Message] をクリックすると、メッセージが送信されます。


JobSchedulerの実行結果は下図のとおり。
job001⇒job200の順番でジョブが実行され、AWSから受信したメッセージが表示されています。