月: 2020年2月

  • redash API で パラメータを動的に変えてクエリを受け付ける

    redash API で パラメータを動的に変えてクエリを受け付ける

    tl;dr;

    redash API で パラメータを動的に変えてクエリを受け付ける方法を紹介します。

    サードパーティを使わず行います。今回の version は redash v6ですがおそらくそれ以降でも可能かと思います。

    手順をご紹介する前の前提条件

    私の環境では検証環境としてすぐ起動できる redash の環境を利用します。

    # git clone
    git clone https://github.com/GitSumito/redash-blue.git
    cd redash-blue
    
    # DB 初期化
    docker-compose run --rm server create_db docker-compose up
    
    # 起動
    docker-compose up -d  

    http://127.0.0.1/ へ接続し、データソースの設定などを適宜行います。

    DBのcredential 情報などは下記をご覧ください。

    https://github.com/GitSumito/redash-blue/blob/master/README.md

     

    動的クエリを作成する

    その後、 Create -> Query に移動し、変数を受け付けるカラムを書きます。

    この場合はクエリを code という引数で受け取ります。

     code に JPN といれると、redash が where ContryCode = "JPN"と組み立ててくれる仕組みです。

    これをブラウザからではなく、RestFull API で行うようにするというのが今回の趣旨です。

    作成した Query は publish してください、

    事前準備

    ユーザーのAPI keyを確認します。

    http://127.0.0.1/users/1

    を開けばAPI keyを確認することができます。

    このAPI keyを確認します。

    ジョブを登録する

    引数は p_xxxx というパラメータ名で受け付けるようです。
    code という引数を設定したので、今回は p_code というパラメータ名になりました。

    これを POST で送ります。curl コマンドで行うとやりやすいかと思います。

    curl --request POST \
    --url 'http://127.0.0.1/api/queries/1/refresh?p_code=IND' \
    --header 'Authorization: Key ajxxxxxxxxxxxxxxx'

    受け付けられると、 以下のようなレスポンスが返ってきます。

    ID を控えてください。今回登録したジョブを、以下のIDを用いて確認することができます。

    query_result_id を確認する

    ジョブのIDをパスパラメータとして渡します。

    また、api_keyを後ろにつけてください。

    curl "http://127.0.0.1/api/jobs/93452aa6-8569-43fc-b816-cb441ce80e03?api_key=ajxxxxxxxxxxxxxxx"

    query_result_id が返ってきます。こちらを用いて結果を確認します。

    query_result_id を用いて結果を確認する

     

    curl -s -H 'Authorization:Key ajxxxxxxxxxxxxxxx' -H 'Accept:application/json' -H 'Content-Type:application/json' http://127.0.0.1/api/query_results/8
    

    以下の通り、ContryCode `IND`の情報を取得することができました。

    今回の version は redash v6ですがおそらくそれ以降でも可能かと思います。

  • ECS Scheduling tasks の FailedInvocations を対処する

    ECS Scheduling tasks の FailedInvocations を対処する

    tl;dr;

    ECS のタスクスケジューリングで

    FailedInvocations が発生するのは、CloudWatch eventsでの実行ロールに権限が足りないから。その対処方法をまとめる。

    IAM ロール

    I AM ロールを作成する。

    今回は ecsEventsRole という名前にした。

    作成したロールの信頼関係を編集。

    cloudwatch events から実行できるよう権限を付与。

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "",
          "Effect": "Allow",
          "Principal": {
            "Service": "events.amazonaws.com"
          },
          "Action": "sts:AssumeRole"
        }
      ]
    }

    以下の通り貼り付ける。

    作成したroleに`AmazonEC2ContainerServiceEventsRole` ポリシーをアタッチする。

    ECS task scheduleで作成したロールをアタッチ

    今回作成した ecsEventsRole を割り当てる。

    動作確認

    CloudWatch メトリクスを確認すると、

    FailedInvocations が解消し Invocations になった。

     

  • embulk に環境変数で接続情報を渡す

    embulk に環境変数で接続情報を渡す

    tl;dr;

    embulk で環境変数を処理することができる.liquid

    について紹介。これを使うことで、docker image を複数環境で起動することができるようになる。

    公式ドキュメント

    以下のような記載がある。

    https://www.embulk.org/docs/built-in.html

    試してみた

    準備

    以下のようなディレクトリ構成

    “`
    ├── Dockerfile
    └── config.yml.liquid

    “`

    それぞれ中身は以下の通り

    FROM java:8
    MAINTAINER sumito.tsukada "tsukada@sumito.jp"
     
    ENV EMBULK_VERSION 0.9.23
     
    RUN curl -L https://bintray.com/artifact/download/embulk/maven/embulk-${EMBULK_VERSION}.jar -o /opt/embulk.jar
    RUN java -jar /opt/embulk.jar gem install embulk-input-mysql
    RUN java -jar /opt/embulk.jar gem install embulk-output-bigquery
    
    COPY config.yml.liquid /work/
     
    WORKDIR /work
    ENTRYPOINT ["java", "-jar", "/opt/embulk.jar", "run", "/work/config.yml.liquid"]

    受け取る側には {{env.}} を接頭辞として付ける。

    in:
      type: mysql
      user: {{env.DB_USER}}
      password: {{env.DB_PASS}}
      database: {{env.DB_NAME}}
      host: {{env.DB_HOST}}
      query: {{env.DB_QUERY}}
    out: {type: stdout}

    build

    docker build コマンドでビルドする。

    $ docker build -t tsukada/embulk .
    Sending build context to Docker daemon  3.072kB
    Step 1/9 : FROM java:8
     ---> d23bdf5b1b1b
    Step 2/9 : MAINTAINER sumito.tsukada "tsukada@sumito.jp"
     ---> Using cache
     ---> 5fc85815e7bd
    Step 3/9 : ENV EMBULK_VERSION 0.9.23
     ---> Using cache
     ---> d449016ef749
    Step 4/9 : RUN curl -L https://bintray.com/artifact/download/embulk/maven/embulk-${EMBULK_VERSION}.jar -o /opt/embulk.jar
     ---> Using cache
     ---> ea1d918c1c64
    Step 5/9 : RUN java -jar /opt/embulk.jar gem install embulk-input-mysql
     ---> Using cache
     ---> e7057cd4cefe
    Step 6/9 : RUN java -jar /opt/embulk.jar gem install embulk-output-bigquery
     ---> Using cache
     ---> 01d70f5dc598
    Step 7/9 : COPY config.yml.liquid /work/
     ---> Using cache
     ---> 8f7529947df8
    Step 8/9 : WORKDIR /work
     ---> Using cache
     ---> 7d4b1d4ea599
    Step 9/9 : ENTRYPOINT ["java", "-jar", "/opt/embulk.jar", "run", "/work/config.yml.liquid"]
     ---> Using cache
     ---> 8161e0f70fde
    Successfully built 8161e0f70fde
    Successfully tagged tsukada/embulk:latest

    使い方

    環境変数に接続先情報や、クエリの情報を渡す。

    $ docker run -e DB_USER=tsukada -e DB_PASS=password -e DB_NAME=database -e DB_HOST=hogehoge.ap-northeast-1.rds.amazonaws.com  -e DB_QUERY="select * from sample" --rm -it tsukada/embulk
    2020-02-18 03:43:44.882 +0000: Embulk v0.9.23
    (中略)
    2020-02-18 03:43:52.822 +0000 [INFO] (0015:task-0000): > 0.00 seconds
    1,tsukada,hoge,,2020-02-14 09:14:31,2020-02-14 09:14:32,84,004,2020-02-14 09:14:31,2020-02-14 09:14:31
    2020-02-18 03:43:52.913 +0000 [INFO] (0001:transaction): {done:  1 / 1, running: 0}
    2020-02-18 03:43:52.917 +0000 [INFO] (main): Committed.
    2020-02-18 03:43:52.917 +0000 [INFO] (main): Next config diff: {"in":{},"out":{}}

    .liquid ファイル内では env. で受け取るが、docker 起動する際に渡す環境変数には、env を付けづに実行する。

    無事データを取得することができた。

    所感

    これを使えば、コンテナ内にcredential情報を保持しなくて済むようになるため、1つのcontainer imageで、複数環境で動かすことができそうだ。

  • org/embulk/cli/Main : Unsupported major.minor version 52.0

    org/embulk/cli/Main : Unsupported major.minor version 52.0

    tl;dr;

    embulk をbuild しようとすると ` Unsupported major.minor version 52.0` というエラーが出るようになった。原因と対処について紹介。

    元にした作業手順(2018年だから、もう2年も前だ。。)

    https://tsukada.sumito.jp/2018/09/18/mysql%e3%81%ae%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92embulk%e3%81%a7bigquery%e3%81%b8%e5%85%a5%e3%82%8credash%e3%81%a7%e7%a2%ba%e8%aa%8d%e3%81%99%e3%82%8b/

    エラー詳細

    Exception in thread "main" java.lang.UnsupportedClassVersionError: org/embulk/cli/Main : Unsupported major.minor version 52.0
    	at java.lang.ClassLoader.defineClass1(Native Method)
    	at java.lang.ClassLoader.defineClass(ClassLoader.java:803)
    	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    	at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    	at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    	at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    	at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    	at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)

    原因

    embulk でjava 7のサポートが切れた。build する際にプラグインの組み込み段階でエラーになる。

    対処

    embulk のベースの docker image を

    `FROM java:7` から

    `FROM java:8` に変更する。

    サンプル

    FROM java:8
    MAINTAINER sumito.tsukada "tsukada@hoge.jp"
     
    ENV EMBULK_VERSION 0.9.23
     
    RUN curl -L https://bintray.com/artifact/download/embulk/maven/embulk-${EMBULK_VERSION}.jar -o /opt/embulk.jar
    RUN java -jar /opt/embulk.jar gem install embulk-input-mysql
    RUN java -jar /opt/embulk.jar gem install embulk-output-bigquery
     
    WORKDIR /work
    ENTRYPOINT ["java", "-jar", "/opt/embulk.jar"]
    CMD ["--help"]