【Salesforce】シェルで外部サーバからApexBatchを起動する。

## 概要

データ連携の選択肢として、大量データかつトランザクションが必要な場合は
**BulkAPI** + **テンポラリテーブル** + **Apex Batch**という選択肢が考えられます。
ただApex BatchはSalesforce側のスケジュール設定、Bulk APIでの連携処理は外部サーバのジョブスケジューラの設定となります。

エラーハンドリングの処理を考えると外部サーバ側でスケジュール設定はまとめておきたいところです。

外部サーバ側でスケジュール設定をまとめるには
webserviceを作成し、SOAP APIを利用してApex Batchを起動することにより外部サーバからの起動が可能になります。

今回はシェルから起動する方法を紹介します。

## Apex Batchを作成する。

```
public with sharing class HogeBatchExecute implements Database.Batchable<sObject>, Database.Stateful {
    ･･･
}
```

## webserviceを登録する
```
global class GlobalCallBatchs {
    private final Integer BATCH_SIZE = 200;
    
    webservice static Boolean callHogeBatch(){
        Boolean ret;
        try {
            HogeBatchExecute b = new HogeBatchExecute();
            database.executebatch(b, BATCH_SIZE);
            ret = true;
        }catch(Exception e){
            ret = false;
        }
        return ret;
    }
}
```

## ログイン用のxmlを用意する。
```xml:login.xml
<?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body>
<n1:login xmlns:n1="urn:partner.soap.sforce.com">
<n1:username>hogehoge@example.com</n1:username>
<n1:password>hogehoge</n1:password>
</n1:login>
</env:Body>
</env:Envelope>
```

## ログイン
```linux
curl https://login.salesforce.com/services/Soap/u/39.0 -H "Content-Type: text/xml; charset=UTF-8" -H "SOAPAction: login" -d @login.xml
```

## 返却値よりセッションIDを抜き出す
```xml
<sessionId>00DA0000000AXPZ!AQYAQC1_3X1zuSc47y75CU5a4omSypSox6Bg.j.hIsGDBv9hnc7b9ZAD.98ZST3jYxwqoY5TyF4VR7YDUxfWn.ZmeDnoY1Nv</sessionId>
```

## webservice起動用のxmlファイルを用意する。
```xml:callHogeBatch.xml
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cal="http://soap.sforce.com/schemas/class/GlobalCallBatchs">
   <soapenv:Header>
      <cal:AllowFieldTruncationHeader>
         <cal:allowFieldTruncation>true</cal:allowFieldTruncation>
      </cal:AllowFieldTruncationHeader>
      <cal:DebuggingHeader>
         <!--Zero or more repetitions:-->
         <cal:categories>
            <cal:category>Apex_code</cal:category>
            <cal:level>Debug</cal:level>
         </cal:categories>
         <cal:debugLevel>Debugonly</cal:debugLevel>
      </cal:DebuggingHeader>
      <cal:CallOptions>
         <cal:client></cal:client>
      </cal:CallOptions>
      <cal:SessionHeader>
         <cal:sessionId>00DA0000000AXPZ!AQYAQC1_3X1zuSc47y75CU5a4omSypSox6Bg.j.hIsGDBv9hnc7b9ZAD.98ZST3jYxwqoY5TyF4VR7YDUxfWn.ZmeDnoY1Nv</cal:sessionId>
      </cal:SessionHeader>
   </soapenv:Header>
   <soapenv:Body>
      <cal:callHogeBatch/>
   </soapenv:Body>
</soapenv:Envelope>
```

## バッチの起動
```
curl https://instance.salesforce.com/services/Soap/class/GlobalCallBatchs -H "Content-Type: text/xml; charset=UTF-8" -H "SOAPAction: login" -d @callHogeBatch.xml
```

## 返却値
```xml
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://soap.sforce.com/schemas/class/GlobalCallBatchs">
<soapenv:Header>
<DebuggingInfo>
<debugLog>36.0 APEX_CODE,DEBUG
13:28:52.1 (1181977)|USER_INFO|[EXTERNAL]|00000000000ylVM|hogehoge@example.com|日本標準時|GMT+09:00
13:28:52.1 (1206879)|EXECUTION_STARTED
13:28:52.1 (1211313)|CODE_UNIT_STARTED|[EXTERNAL]|000000000008Vj3|GlobalCallBatchs.callHogeBatch
13:28:52.1 (83633383)|CODE_UNIT_FINISHED|GlobalCallBatchs.callHogeBatch
13:28:52.1 (84368787)|EXECUTION_FINISHED
</debugLog>
</DebuggingInfo>
</soapenv:Header>
<soapenv:Body>
<doBatchResponse>
<result>true</result>
</doBatchResponse>
</soapenv:Body>
</soapenv:Envelope>
```