MacでAWS Glueを実行したい（実行編）

# 概要
- ローカルでGlueを実行する方法を記載します
- 実行内容は以下になります
 - S3からJsonファイルを読み込む
 - ETLしてTSVファイルを出力する

# 環境
- [環境構築編](https://qiita.com/supring/items/babc1c95d0cef1a67442)をご覧ください

# 参考
- Classmethodさん https://dev.classmethod.jp/articles/aws-glue-local/

# 手順
1. LocalStackの準備
2. spark config設定
3. s3準備
4. 実行用scriptの準備

# 1. LocalStackの準備
## LocalStackとは
- AWSのモックフレームワークを提供してくれる物です
 - 引用&参考(ClassMethodさん)　: https://dev.classmethod.jp/articles/localstack-lambda/

## docker-compose.ymlを作成
- AWS Glue Pythonライブラリをダウンロードした `~/Desktop/local_glue/` に作成します

```
cd ~/Desktop/local_glue/

vi docker-compose.yml

version: "3.3"

services:
  localstack:
    container_name: localstack
    image: localstack/localstack
    ports:
      - "8080:8080"
      - "4569:4569"
      - "4572:4572"
    environment:
      - DEFAULT_REGION=ap-northeast-1
      - SERVICES=s3
```

## aws認証情報設定
- 環境変数に設定してないとエラーとなるので設定しておく

```
export AWS_ACCESS_KEY_ID='dummy'
export AWS_SECRET_ACCESS_KEY='dummy'
export AWS_REGION='ap-northeast-1'
```

## docker起動

```
docker-compose up -d
```

# 2.spark config設定
- 以下のファイルに設定を追加します

```shell

vi aws-glue-libs/bin/glue-setup.sh

#!/usr/bin/env bash

ROOT_DIR="$(cd $(dirname "$0")/..; pwd)"
cd $ROOT_DIR

SPARK_CONF_DIR=$ROOT_DIR/conf
GLUE_JARS_DIR=$ROOT_DIR/jars

PYTHONPATH="$SPARK_HOME/python/:$PYTHONPATH"
PYTHONPATH=`ls $SPARK_HOME/python/lib/py4j-*-src.zip`:"$PYTHONPATH"

# Generate the zip archive for glue python modules
rm PyGlue.zip
zip -r PyGlue.zip awsglue
GLUE_PY_FILES="$ROOT_DIR/PyGlue.zip"
export PYTHONPATH="$GLUE_PY_FILES:$PYTHONPATH"

# Run mvn copy-dependencies target to get the Glue dependencies locally
mvn -f $ROOT_DIR/pom.xml -DoutputDirectory=$ROOT_DIR/jars dependency:copy-dependencies

export SPARK_CONF_DIR=${ROOT_DIR}/conf
mkdir $SPARK_CONF_DIR
rm $SPARK_CONF_DIR/spark-defaults.conf
# Generate spark-defaults.conf
echo "spark.driver.extraClassPath $GLUE_JARS_DIR/*" >> $SPARK_CONF_DIR/spark-defaults.conf
echo "spark.executor.extraClassPath $GLUE_JARS_DIR/*" >> $SPARK_CONF_DIR/spark-defaults.conf

# ここから追記
echo "spark.hadoop.fs.s3a.endpoint http://localhost:4572" >> $SPARK_CONF_DIR/spark-defaults.conf
echo "spark.hadoop.fs.s3a.path.style.access true" >> $SPARK_CONF_DIR/spark-defaults.conf
echo "spark.hadoop.fs.s3a.signing-algorithm S3SignerType" >> $SPARK_CONF_DIR/spark-defaults.conf
# ここまで追記

# Restore present working directory
cd -
```

- spark configの設定ですが、 以下のファイルに書くわけではありません

```
spark-2.2.1-bin-hadoop2.7/conf/spark-defaults.conf
```
# 3. s3の準備
- bucketの作成

```
aws s3api create-bucket \
    --bucket test \
    --endpoint-url http://localhost:4572
```
-　ファイルの準備

```shell
vi test.csv

1,cake
2,pudding
3,cookie
```

- ファイルの配置

```shell
aws s3 cp test.csv s3://test/ --endpoint-url http://localhost:4572
```

# 4. 実行用スクリプト準備
 - ~/Desktop/local_glue/aws-glue-libs/src/test.py を準備

```python

import sys
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job
from awsglue.dynamicframe import DynamicFrame



JOB_NAME = "test"

sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(JOB_NAME)

datasource = glueContext.create_dynamic_frame.from_options(
    connection_type='s3',
    connection_options={
        "paths": ["s3://test/test.csv"]
    },
    format="csv"
)

datasource_df = datasource.toDF()
datasource_df.show()
datasource_df.registerTempTable("dessert_table")

spark.sql("show tables").show()
df1 = spark.sql("SELECT *  from dessert_table")


df1.show()
job.commit()
```

- Glue 起動

```shell
cd ~/Desktop/local_glue/aws-glue-libs/

./bin/gluesparksubmit ./src/test.py
```