Salesforce
docker
DataLoader

Dataloader Docker環境でのCSVファイルダウンロード

はじめに

一つ前の記事で作成したDataloaderのDcokerコンテナを使用して、SalesforceのデータをCSVでダウンロードします。データローダを使ってバッチでのCSVファイルのダウンロードは他に良い記事を探していただくとして、ここでは前の記事のDockerコンテナを使うサンプルとして説明します。

前提条件

ファイル

作成する場所を~/CSVDownloadとしたときにその下にbin,conf,dataフォルダを作成し、次のファイルを用意してください。bitbucketのリポジトリからも取得できます

  • ~/CSVDownload/Dockerfile
  • ~/CSVDownload/bin/create_config.sh
  • ~/CSVDownload/bin/extract_csv.sh
  • ~/CSVDownload/conf/accountExtractMap.sdl
  • ~/CSVDownload/conf/process-conf.xml
    フォルダ階層がうまく書けない(ioi)
FROM okazakiyuji/dataloader
MAINTAINER okazakiyuji
RUN localedef -f UTF-8 -i ja_JP /usr/lib/locale/ja_JP.UTF-8
ENV LANG="ja_JP.UTF-8" \
    LANGUAGE="ja_JP:ja" \
    LC_ALL="ja_JP.UTF-8" \
    TZ="Asia/Tokyo"
RUN yum -y install expect
WORKDIR $DL_ROOT
#
ARG SITE=$SITE
ARG USRNAME=$USRNAME
ARG PASSWD=$PASSWD
COPY conf ./conf
COPY bin ./bin
RUN chmod a+x ./bin/create_config.sh
RUN chmod a+x ./bin/extract_csv.sh
RUN create_config.sh $SITE $USRNAME $PASSWD
# RUN cat conf/config.properties
CMD ["extract_csv.sh"]

Dockerfileの概要は次のようになっています
* ベースのイメージに一つ前の記事で作成したDataloaderコンテナを使用
* ロケール関連の設定
* 必要なファイルのインストール
* ローカルのファイルをコンテナにコピー
* create_config.shでエンコード済パスワードやプロキシ設定をconfig.propertiesファイルに設定し
* 実行時にextract_csv.shを実行する

accountExtractMap.sdl
id=id
ISDELETED=ISDELETED
NAME=NAME
TYPE=TYPE
PARENTID=PARENTID
OWNERID=OWNERID
CREATEDDATE=CREATEDDATE
CREATEDBYID=CREATEDBYID
LASTMODIFIEDDATE=LASTMODIFIEDDATE
LASTMODIFIEDBYID=LASTMODIFIEDBYID
ISPARTNER=ISPARTNER
ISCUSTOMERPORTAL=ISCUSTOMERPORTAL

皆さんご存知のSDLファイルですね。GUIありのデータローダで作ってしまってそのファイルで置き換えても大丈夫です。

process-conf.xml
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean id="csvAccountExtractProcess"
          class="com.salesforce.dataloader.process.ProcessRunner"
          singleton="false">
      <description>csvAccountExtract job gets Account info and saves info into a CSV file."</description>
        <property name="name" value="csvAccountExtract"/>
        <property name="configOverrideMap">
            <map>
                <entry key="sfdc.entity" value="Account"/>
                <entry key="sfdc.extractionSOQL" value="SELECT id, ISDELETED, NAME, TYPE, PARENTID, OWNERID, CREATEDDATE, CREATEDBYID, LASTMODIFIEDDATE, LASTMODIFIEDBYID, ISPARTNER, ISCUSTOMERPORTAL FROM Account"/>
                <entry key="process.operation" value="extract"/>
                <entry key="process.mappingFile" value="/opt/dataloader/conf/accountExtractMap.sdl"/>
                <entry key="dataAccess.type" value="csvWrite"/>
                <entry key="dataAccess.name" value="/opt/dataloader/data/accoutExtract.csv"/>
            </map>
        </property>
    </bean>
</beans>

Accountダウンロードのbeanだけが書いてあります。他のオブジェクトをダウンロードしたい場合はAccountを文字列置換し、SDLファイルとSOQLを作り直してください.SOQLはAccountのものをまねて、SDLファイルにある項目をずら~と並べたり、GUIありのデータローダから持ってくればOkです。

create_config.sh
#!/bin/bash
cd "`dirname "$0"`"
CONF_ROOT=$DL_ROOT/conf
KEY_FILE=$DL_ROOT/conf/key.txt
if [ x$DL_ROOT = x ] ; then
    echo データローダのインストールルートを DL_ROOTに設定してください
    exit 1
fi
if [ ! x$3 = x ] ; then
    # 引数に何か設定されていたら環境変数を上書きする
    SITE=$1
    USRNAME=$2
    PASSWD=$3
fi
if [ x$SITE = x -o x$USRNAME = x -o x$PASSWD = x ] ; then
    echo "usage"
    echo "    arg1:site name (ex. login.salesforce.com, test.salesforce.com)"
    echo "    arg2:username"
    echo "    arg3:password"
    exit 1
fi
if [ ! -d $CONF_ROOT ] ; then
    echo $CONF_ROOT を作成してください
    exit 1
fi
if [ -f $KEY_FILE ] ; then
    echo $KEY_FILE を削除します
    rm $KEY_FILE
fi
# 暗号化済パスワードを作成する
java -cp $DATALOADER_CLASSPATH com.salesforce.dataloader.security.EncryptionUtil -e $PASSWD $KEY_FILE > /dev/null
if [ $? = 0 ] ; then
    # V42.1.0では-e オプション一発で作成できたが
    ENC_PW=`java -cp $DATALOADER_CLASSPATH com.salesforce.dataloader.security.EncryptionUtil -e $PASSWD $KEY_FILE | sed -n 2P`
else
    KEYWD=`mkpasswd -s 0 -d 0 -l 16`
    java -cp $DATALOADER_CLASSPATH com.salesforce.dataloader.security.EncryptionUtil -g $KEYWD | sed -e "s/.* - //1" > $KEY_FILE
    ENC_PW=`java -cp $DATALOADER_CLASSPATH com.salesforce.dataloader.security.EncryptionUtil -e $PASSWD $KEY_FILE | sed -e "s/.* - //1"`
fi
echo "# config.properties" > $CONF_ROOT/config.properties
echo process.encryptionKeyFile=$KEY_FILE >> $CONF_ROOT/config.properties
echo sfdc.endpoint=https://$SITE >> $CONF_ROOT/config.properties
echo sfdc.username=$USRNAME >> $CONF_ROOT/config.properties
echo sfdc.password=$ENC_PW >> $CONF_ROOT/config.properties
echo sfdc.timeoutSecs=600 >> $CONF_ROOT/config.properties
echo sfdc.loadBatchSize=200 >> $CONF_ROOT/config.properties
echo sfdc.extractionRequestSize=500 >> $CONF_ROOT/config.properties
echo sfdc.debugMessages=false >> $CONF_ROOT/config.properties
echo sfdc.debugMessagesFile=/opt/dataloader/status/debug.log >> $CONF_ROOT/config.properties
# Proxy設定の出力 (動作確認未)
if [ x$https_proxy != x ]; then
    PROXY_STR=${https_proxy/*:\/\//}
    WORK=${PROXY_STR%@*}
    if [ x$WORK != x$PROXY_STR ]; then
        echo sfdc.proxyUsername=${WORK%:*} >> $CONF_ROOT/config.properties
        echo sfdc.proxyPassword=${WORK#*:} >> $CONF_ROOT/config.properties
        WORK=${PROXY_STR#*@}
    fi
    echo sfdc.proxyHost=${WORK%:*} >> $CONF_ROOT/config.properties
    echo sfdc.proxyPort=${WORK#*:} >> $CONF_ROOT/config.properties
fi

暗号化したパスワードやproxyを引数や環境変数から読み取りconfig.propertiesに設定します。

extract_csv.sh
#!/bin/bash
cd "`dirname "$0"`"
if [ x$DL_ROOT = x ] ; then
    DL_ROOT=$DL_BIN_DIR/..
fi
CONF_DIR=$DL_ROOT/conf
function dl_process () {
    # Dataloader のプロセスを実行する
    echo process: $1
    java -cp $DATALOADER_CLASSPATH -Dsalesforce.config.dir=$CONF_DIR \
        com.salesforce.dataloader.process.ProcessRunner process.name=$1 # > /dev/null
}

dl_process csvAccountExtractProcess

CSVダウンロードを実行するコマンドです。単純にプロセスを読んでいるだけです。

確認方法

ビルドする

コンテナをビルドします。SITEは本番環境ならlogin.salesforce.com, sandboxではtest.salesforce.comを指定してください。他はデータローダのGUIあり版で指定しているものを指定してください。proxyあり環境の場合は--build-argでhttp_proxyとhttps_proxyを指定するとかしてください。https_proxyを指定しておくと、確認はできていませんが、config.propertiesにProxy関連の必要な情報が出力されます。

$ cd ~/CSVDownload
$ sudo docker build . --tag dlcsv --build-arg SITE=login.salesforce.com --build-arg USRNAME=~~@~~.~~~.com --build-arg PASSWD=~~~~~????

(2018/06/25追加)config.propertiesの例です。このように主に接続に必要な項目が出力されるのでprocess.xmlに足りない値を記述してください。

/opt/dataloader/conf/config.properties
# config.properties
process.encryptionKeyFile=/opt/dataloader/conf/key.txt
sfdc.endpoint=https://*****.salesforce.com
sfdc.username=~~@~~.~~~.com
sfdc.password=************************************************************************************
sfdc.timeoutSecs=600
sfdc.loadBatchSize=200
sfdc.extractionRequestSize=500
sfdc.debugMessages=false
sfdc.debugMessagesFile=/opt/dataloader/status/debug.log

実行する

実行例です。ローカルフォルダ$PWD/dataをコンテナにマウントし実行します。エラーが発生しなければ、ダウンロードしたファイルがdataフォルダの下に作成されます

$ mkdir -p $PWD/data
$ sudo docker run -v$PWD/data:/opt/dataloader/data -t dlcsv
$ cat data/accoutExtract.csv