【SCP】ABAPからSCPのWorkflowを起動する

##はじめに
この記事は [SAP Advent Calendar 2020](https://adventar.org/calendars/5047) の12月6日分の記事として執筆しています。

###やりたいこと
SAP Could PlatformのワークフローをABAPから起動します。参考にしたのは以下のブログです。
[Call SAP Cloud Platform Workflow from ABAP using an OAuth access token](https://blogs.sap.com/2019/07/24/call-sap-cloud-platform-workflow-from-abap-using-an-oauth-access-token/)
ブログではNeo環境のワークフローを呼んでいますが、今回はCloud Foundryのワークフローを呼びます。Cloud FoundryではAPIが変わりますが、基本的な流れは同じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/edc33cb6-5a22-fa81-f93d-cf1a84bdfabf.png)

###認証の流れ
SCP上のサービスのAPIを呼ぶ際の認証の流れは以下のようになります。

①トークンを発行するためのエンドポイントにアクセス（クライアントID、シークレットを渡す）
②トークンが返される（権限のスコープなどが渡される）
③トークンを使用してAPIにアクセス（APIエンドポイント側で権限チェック）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/775c71ff-ef13-29ed-ab85-c9991107b911.png)

UIを伴うアプリの場合は[こちらの記事](https://qiita.com/tami/items/77f8cad68cfd6975c9c0#cloud-platform%E3%81%A7%E3%81%AE%E3%83%A6%E3%83%BC%E3%82%B6%E8%AA%8D%E8%A8%BC%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF)で紹介したようにユーザID、パスワードの入力が求められますが、今回は[テクニカルな認証](https://help.sap.com/viewer/e157c391253b4ecd93647bf232d18a83/Cloud/en-US/c74f5ff9065b4baeb700d033602ef1d9.html)ということで、ユーザによる入力は不要です。

認証の手順はワークフローに限らずSCP上のサービスのAPIを呼ぶときに共通なので、一度やり方を押さえれば他のサービスに接続する際にも応用することができます。

##ステップ
1. SCP側の設定
 1.1. 事前準備
 1.2. ワークフロー作成
 1.3. ワークフローのテスト
 1.4. PostmanでワークフローのAPIを叩いてみる

2. ABAP側の設定
 2.1. Destinationの設定
 2.2. SSLの設定
 2.3. プロファイルパラメータの更新
 2.4. ABAPコード

###1. SCP側の設定
####1.1. 事前準備
このステップではSCPのワークフローを使えるようにします。前提として、SCPの[トライアルアカウント](https://developers.sap.com/tutorials/hcp-create-trial-account.html)が必要です。

以下のページを参考に必要な設定を行います。
[Setting up for Workflow on SAP Cloud Platform](https://github.com/SAP-samples/cloud-platform-workflow-virtual-event/blob/master/exercises/01/readme.md)

やるとことは大きく2つです。
1. Boosterを使ってワークフローを使用するための設定を自動で実施
2. Business Application Studioにワークフロー開発用のスペースを作成

私の場合はすでにFiori用に作ったスペースがあったので、Workflow Managementのエクステンションを追加しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/79c420dc-739f-fd0d-1177-6e4096de1267.png)

####1.2. ワークフロー作成
以下のチュートリアルグループを参考に、Business Application Studioでワークフローを作成します。
[Get Started with SAP Cloud Platform Workflow](https://developers.sap.com/group.cp-workflow-cf.html)　
チュートリアルグループには3つのチュートリアルがありますが、最初の2つまででOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/c387293a-f48a-2a48-428e-861c19a02a67.png)

チュートリアルから変更した点が2つあります。
**①ユーザタスクの受信者**　（[チュートリアル2のステップ1](https://developers.sap.com/tutorials/cp-workflow-3-add-usertask-cf.html#99219d39-3207-4c3e-9897-4e6a90c85251)）
チュートリアルではタスクの受信者にワークフローを起動したユーザを指定していますが、ABAPから実行した場合は起動したユーザがSCPのユーザにならないので、固定値でSCPに登録した自分のメールアドレスを指定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/d2c51c00-b2f8-01bf-c402-b42e145d02b1.png)

**②ワークフローのサービスインスタス**　（[チュートリアル2のステップ4](https://developers.sap.com/tutorials/cp-workflow-3-add-usertask-cf.html#73e12c13-fc2d-4166-a9a8-e72a449be8ed)）
Boosterを使ったことにより、使用するサービスインスタンスに変更が必要です。Boosterは`default_workflow`というサービスインスタンスを作っているのでそれを使うようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/b47f8545-bd5e-b86b-1636-671c8950cd5d.png)
mta.yaml
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/0011813c-0e62-d042-55d2-c5945d17d423.png)

または、以下のように新しいサービスインスタンスを作成するようにしてもよいです。resourcesのtypeが`org.cloudfoundry.existing-service`となっていると既存のサービスインスタンスが使われ、`org.cloudfoundry.managed-service`となっていると新規のサービスインスタンスが作られます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/f302197a-3d9c-5254-4742-a5a5e7610614.png)

####1.3. ワークフローのテスト
デプロイができたら[チュートリアル2のステップ5](https://developers.sap.com/tutorials/cp-workflow-3-add-usertask-cf.html#34921b0e-4a86-4b9e-bb5f-6659ea462853)の要領で、ワークフローインスタンスを開始してみます。うまくいけばMy Inboxアプリで以下のようにタスクを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/6d471ff7-3f5d-b080-5808-b101682c0cd5.png)

####1.4. PostmanでワークフローのAPIを叩いてみる
ABAPからワークフローのAPIを呼ぶにあたり、Postmanを使ってリクエストに必要なパラメータを確認しておきましょう。APIを呼ぶのに必要な情報はワークフローのサービスキーから確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/8347971b-0762-3e66-3ed3-ae34cfdcb47b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/b082b68d-a315-eca1-c59c-c763ec26077a.png)

**①トークンを取得**
以下のパラメータを設定してリクエストを実行します。

|パラメータ    |設定値      |      |
|:----------|:---------------|:---------------|
| HTTPメソッド   |POST        |        |
| URL   |<サービスキーのuaa.url>/oauth/token  |        |
| Headers   |Content-Type        |application/x-www-form-urlencoded  |
|    |Accept        |application/json     |
| Body   |client_id        |<サービスキーのuaa.clientid>  |
|    |client_secret        |<サービスキーのuaa.clientsecret>  |
|    |grant_type        |client_credentials  |
|    |response_type        |token  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/a4de5742-8126-6709-92a2-8bbf13bf9653.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/3462859c-253c-a52e-0ebb-fd3076ee8073.png)
アクセストークンが返ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/77bd962b-aa14-ef83-9eb1-510380e9229e.png)

**②APIでワークフローを起動**
ワークフローのAPIは[API Hub](https://api.sap.com/api/SAP_CP_Workflow_CF/resource)で確認できます。ここではワークフローのインスタンスを生成する`/v1/workflow-instances`を使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/6038d27f-928f-7306-1cac-b2ef3b7a5917.png)

以下のパラメータを設定してリクエストを実行します。

|パラメータ    |設定値      |      |
|:----------|:---------------|:---------------|
| HTTPメソッド   |POST        |        |
| URL   |<サービスキーのendpoints.workflow_rest_url>/v1/workflow-instances  |        |
| Headers   |Authorization        |Bearer <①で取得したaccess_token>  |
|    |application/json        |application/json     |

Bodyには以下のJSONオブジェクトを設定します。definitionIdにワークフローのIDを、contextにワークフローに渡すパラメータを設定します。

```json
{
    "definitionId": "onboard",
    "context": {
        "managerId": "john.edrich@sapdemo.com",
        "buddyId": "kevin.hart@saptest.com",
        "userId": "cgrant1",
        "empData": {
            "firstName": "Postman",
            "lastName": "Grant",
            "city": "San Mateo",
            "country": "United States",
            "hireDate": "2020-07-11",
            "jobTitle": "General Manager, Industries"
        }
    }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/49b7672c-9a43-c4cb-ed1d-20985933ea1a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/f234aade-009c-7a06-ed38-e16ab3f5cecd.png)
実行すると以下のような権限なしエラーが返ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/476b714d-e341-3ff4-75ec-2deeba5fa2c4.png)
実はAPIごとに必要な権限がScopeとして定義されおり、サービスインスタンスにこのScopeを追加する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/f6d58bae-e393-2db3-eb4f-2b160f8443be.png)
以下のコマンドでサービスインスタンスにScopeを追加します。（ここではワークフロー起動の権限とワークフロー定義の表示の権限を追加しています）

```
cf update-service default_workflow -c '{"authorities": ["WORKFLOW_DEFINITION_GET", "WORKFLOW_INSTANCE_START"]}'
```

※Windowで実行の場合はシングルクォートが使えないので、以下のように指定する必要があります。

```
cf update-service default_workflow -c "{\""authorities\"": [\""WORKFLOW_DEFINITION_GET\"", \""WORKFLOW_INSTANCE_START\""]}"
```

もう一度ワークフロー起動のリクエストを実行すると、今度は以下のような結果が返されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/07dc038d-7e21-12e5-144a-64c3c9df1e69.png)
My Inboxアプリからタスクを確認することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/0fabba99-7369-06f5-76a5-caeffde5c35b.png)

以上でSCP側の設定は完了です。

###2. ABAP側の設定
####2.1. Destinationの設定
トークン取得用の宛先とAPI呼び出し用の宛先をtr-cd:`SM59`で登録します。

**①トークン取得用の宛先**
以下のパラメータを設定します。

|タブ    |パラメータ      |設定値      |
|:----------|:---------------|:---------------|
| Technical Settings   |Host        |<サービスキーのuaa.url> ※https://はつけない|
| Logon & Security   |Basic Authentication        |選択|
|    |User        |<サービスキーのuaa.clientid>|
|    |Password        |<サービスキーのuaa.cliensecret>|
|    |SSL        |Active|
|    |SSL Certificate        |ANONYM SSL Client(Anonymous)|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/f0c1015f-3a9d-aab3-e02c-68a16235c43b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/1fa1fa89-72d6-c5d9-fdc1-ae7b5cc6039a.png)

**②API用の宛先**
以下のパラメータを設定します。Logon & Securityタブは設定不要です。

|タブ    |パラメータ      |設定値      |
|:----------|:---------------|:---------------|
| Technical Settings   |Host        |<サービスキーのendpoints.workflow_rest_url> ※https://はつけない|
|    |Path Prefix        |/workflow-service/rest|
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/fc02004e-a9a4-db65-13f5-5ef2cb8cfa56.png)

2022/1/20更新
OAuth 2.0 Client Profileの設定をすることで、トークン取得用の宛先を作らなくてもよくなります。（詳細は以下のブログ参照）
[Configure SAP Event Mesh for SAP S/4HANA On-Premise](https://blogs.sap.com/2022/01/19/configure-sap-event-mesh-for-sap-s-4hana-on-premise/)

####2.2. SSLの設定
各宛先へはHTTPSで接続するので、SSLの設定が必要です。具体的には、サーバ証明書をダウンロードしてtr-cd:`STRUST`でインポートします。

**①サーバ証明書のダウンロード**
`<サービスキーのuaa.url>`にブラウザからアクセスしてCertificateをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/9c191026-f504-ba45-8b46-845ecc1360f3.png)
証明書タブを開き、「ファイルにコピー」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/45608215-85ca-630d-988d-ca359c58542b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/fe8ea02b-e19d-9faf-4512-e42144e28987.png)
任意の名前を付けて保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/cc58be5d-8d3a-e6e1-ac3f-7eec4c49f73e.png)
これで1つ目の証明書のダウンロードが完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/3e10fafc-760b-93ad-b9ca-84f18afe9aea.png)
「証明書のパス」タブを開き、上位レベルの証明書についても同様にダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/0e3dfb08-464b-4d89-6b17-ac846936bacd.png)

**①サーバ証明書のインストール**
tr-cd:`STRUST`を実行し、変更モードにします。以下の手順で①でダウンロードしたすべての証明書を取り込みます。

- "SSL client SSL Client (Anonymous)フォルダをクリック
- ①のボタンで証明書をインポート
- ②のボタンで証明書リストに追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/048e19d7-912e-c8b5-6251-7d0faad453be.png)

**③接続テスト**
この時点でDestinationの接続テストをしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/afd5375e-d57b-2e9e-57a2-a358a628b7d9.png)
トークン取得用の宛先へは接続できています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/79a22be8-b5ec-8c33-3abe-639df2183b22.png)
API用の宛先は`SSSLERR_SERVER_CERT_MISMATCH`というエラーになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/0b325a9d-31e9-84e7-f4c7-e1dc1447cca9.png)
ICMのトレースを見ると、証明書が対象にしているsubjectと接続しようとしているホスト名が違うようです。API用のエンドポイントについても証明書をインストールしてみましたが、結果は変わりませんでした。（結果として、API用のエンドポイントのサーバ証明書はなくても動きました）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/d2c6470b-ed9f-4091-6664-6e4c0b60adeb.png)

####2.3. プロファイルパラメータの更新
以下のスレッドに類似の質問が投稿されていました。ここで提示されている解決策を試してみたところ、うまくいきました。
https://answers.sap.com/questions/599994/ssslerrservercertmismatch.html

tr-cd:`RZ11`でパラメータ`icm/HTTPS/client_sni_enabled`の値を変更します。デフォルトはFALSEになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/4f4a7a40-c420-18bf-2363-7f94043ba51a.png)
"Change Value"で値を変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/ff70a32a-92bd-16be-6481-efd2cb370688.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/985543d6-2f9f-6b0b-9f78-0a25d31105b7.png)

※RZ11での変更はサーバを再起動するとリセットされてしまうので、パラメータを固定する場合はRZ10で変更します。

プロファイルパラメータの変更後、API用の宛先をテストしてみるとログインを求めるポップアップが出ました。ここまで行けば接続はOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/c5bcee9d-5a28-a0f1-5991-2ead05913d9d.png)

####2.4. ABAPコード
いよいよコーディングです。ADTで新規のクラスを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/750e32ee-2909-c5a0-6410-744c14a11fcb.png)
ここではワークフローのインスタンスを作成してADTのコンソールに結果を表示するというシンプルな処理にします。メソッド`if_oo_adt_classrun~main`に実装していきます。

```abap
CLASS zcl_scp_workflow DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    INTERFACES if_oo_adt_classrun .
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.


CLASS zcl_scp_workflow IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
  ENDMETHOD.
ENDCLASS.
```

**①トークンの取得**
まずは、トークン取得のリクエストを投げて取得したトークンをコンソールに表示します。リクエストのヘッダとボディに設定しているパラメータはPostmanで指定したのと同じです。クライアントID、シークレットはDestinationで設定しているのでここで指定する必要はありません。

```abap
    data lo_client_oauth type ref to if_http_client.
    data lo_client_wfapi TYPE REF TO if_http_client.
    data content type string.
    data lr_json type ref to data.
    data token type string.
    data body type string.

    "1. トークンの取得
    "1.1 Destinationを指定してHTTPクライアントを取得
    cl_http_client=>create_by_destination(
      EXPORTING
        destination              = 'WORKFLOW_OAUTH'                 " Logical destination (specified in function call)
      IMPORTING
        client                   = lo_client_oauth                 " HTTP Client Abstraction
      EXCEPTIONS
        argument_not_found       = 1                " Connection Parameter (Destination) Not Available
        destination_not_found    = 2                " Destination not found
        destination_no_authority = 3                " No Authorization to Use HTTP Destination
        plugin_not_active        = 4                " HTTP/HTTPS communication not available
        internal_error           = 5                " Internal error (e.g. name too long)
        others                   = 6
    ).
    IF sy-subrc <> 0.
      "error handling
    ENDIF.

    "1.2. リクエストヘッダ、ボディの設定
    "Set header
    lo_client_oauth->request->set_header_field( name  = '~request_method' value = 'POST' ).
    lo_client_oauth->request->set_header_field( name  = '~request_uri' value = '/oauth/token' ).
    lo_client_oauth->request->set_header_field( name  = 'Accept' value = 'application/json' ).
    "Set body
    lo_client_oauth->request->set_form_field( name  = 'grant_type' value = 'client_credentials' ).
    lo_client_oauth->request->set_form_field( name  = 'response_type' value = 'token' ).

    "1.3. リクエストを投げる（send, receiveの2ステップ）
    "Get token
    lo_client_oauth->send(
      EXCEPTIONS
        http_communication_failure = 1                  " Communication Error
        http_invalid_state         = 2                  " Invalid state
        http_processing_failed     = 3                  " Error When Processing Method
        http_invalid_timeout       = 4                  " Invalid Time Entry
        others                     = 5
    ).
    IF sy-subrc <> 0.
      "error handling
    ENDIF.
    lo_client_oauth->receive(
      EXCEPTIONS
        http_communication_failure = 1                " Communication Error
        http_invalid_state         = 2                " Invalid state
        http_processing_failed     = 3                " Error When Processing Method
        others                     = 4
    ).
    IF sy-subrc <> 0.
      "error handling
    ENDIF.

    "1.4. HTTPステータスを取得（リクエスト成功かどうか）
    lo_client_oauth->response->get_status( IMPORTING code = data(lv_code) ).

    "1.5. レスポンスをJSONオブジェクトに変換し、"access_token"を取得
    content = lo_client_oauth->response->get_cdata( ).
    lr_json = /ui2/cl_json=>generate( json = content ).
    /ui2/cl_data_access=>create( ir_data = lr_json  iv_component = 'access_token' )->value( IMPORTING ev_data = token ).

    "1.6. ステータスとトークンをコンソールに出力
    out->write( | Response status for Token: { lv_code }, Token: { token } | ).
```
F9キーを押して実行すると、コンソールに以下のようにステータスとトークンが出力されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/59202c87-2d95-fb6e-6271-7a6ba38c9d58.png)

**②APIを呼んでワークフローを起動**
続いて、①で取得したトークンを使用してワークフローのAPIにアクセスします。

```abap
    "2. APIにアクセス
    "2.1. Destinationを指定してAPI接続用のHTTPクライアントを取得
    cl_http_client=>create_by_destination(
      EXPORTING
        destination              = 'WORKFLOW_API'                 " Logical destination (specified in function call)
      IMPORTING
        client                   = lo_client_wfapi                 " HTTP Client Abstraction
      EXCEPTIONS
        argument_not_found       = 1                " Connection Parameter (Destination) Not Available
        destination_not_found    = 2                " Destination not found
        destination_no_authority = 3                " No Authorization to Use HTTP Destination
        plugin_not_active        = 4                " HTTP/HTTPS communication not available
        internal_error           = 5                " Internal error (e.g. name too long)
        others                   = 6
    ).
    IF sy-subrc <> 0.
      "error handling
    ENDIF.

    "2.2. リクエストヘッダ、ボディの設定
    "Set header
    lo_client_wfapi->request->set_header_field( name  = '~request_method' value = 'POST' ).
    lo_client_wfapi->request->set_header_field( name  = '~request_uri' value = '/v1/workflow-instances' ).
    lo_client_wfapi->request->set_header_field( name = 'Content-Type' value = 'application/json' ).
    lo_client_wfapi->request->set_header_field( name  = 'Authorization' value = |Bearer { token }| ).

    "Set body
    concatenate '{ "definitionId": "onboard", "context": { "managerId": "john.edrich@sapdemo.com", "buddyId": "kevin.hart@saptest.com"'
                ', "userId": "cgrant1", "empData": { "firstName": "ABAP", "lastName": "Grant", "city": "San Mateo", "country": "United States", "hireDate": "2020-07-11", "jobTitle": "General Manager, Industries" } } }'
    into body.
    lo_client_wfapi->request->set_cdata( data = body ).


    "2.3. リクエストを投げる（send, receiveの2ステップ）
    lo_client_wfapi->send(
      EXCEPTIONS
        http_communication_failure = 1                  " Communication Error
        http_invalid_state         = 2                  " Invalid state
        http_processing_failed     = 3                  " Error When Processing Method
        http_invalid_timeout       = 4                  " Invalid Time Entry
        others                     = 5
    ).
    IF sy-subrc <> 0.
    ENDIF.
    lo_client_wfapi->receive(
      EXCEPTIONS
        http_communication_failure = 1                " Communication Error
        http_invalid_state         = 2                " Invalid state
        http_processing_failed     = 3                " Error When Processing Method
        others                     = 4
    ).
    IF sy-subrc <> 0.
    ENDIF.

    "2.4. HTTPステータスを取得（リクエスト成功かどうか）
    lo_client_wfapi->response->get_status( IMPORTING code = lv_code ).
    "2.5. レスポンスを取得
    content = lo_client_wfapi->response->get_cdata( ).

    "2.6. ステータスとレスポンスをコンソールに出力
    out->write( | Response status for WF: { lv_code }, Content: { content } | ).
```
以下のようにステータス201が返ってくれば成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/6e2b1078-4136-1058-4a8c-62c823bf4141.png)
My Inboxアプリからタスクを確認することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/bea09d9c-838e-6210-f0af-2b49298c2523.png)

##おわりに
ABAPからSCPへの接続ルートがめでたく開通しました。これができるとSCP上の他のサービスも同じ方法で呼ぶことができ、できることが広がりそうです。

##参考

**ワークフロー**

- [Setting up for Workflow on SAP Cloud Platform](https://github.com/SAP-samples/cloud-platform-workflow-virtual-event/blob/master/exercises/01/readme.md)
- [Get Started with SAP Cloud Platform Workflow](https://developers.sap.com/group.cp-workflow-cf.html)
- [Enable Technical Authentication](https://help.sap.com/viewer/e157c391253b4ecd93647bf232d18a83/Cloud/en-US/c74f5ff9065b4baeb700d033602ef1d9.html)

**APIの呼び方**

- [Calling the Workflow API from Postman](https://github.com/SAP-samples/cloud-platform-workflow-virtual-event/blob/master/exercises/07/readme.md)
- [Note 2760424 - API Access to xsuaa Configuration Data](https://launchpad.support.sap.com/#/notes/2760424)
- [Call SAP Cloud Platform Workflow from ABAP using an OAuth access token](https://blogs.sap.com/2019/07/24/call-sap-cloud-platform-workflow-from-abap-using-an-oauth-access-token/)

**トラブルシューティング**

- [SSSLERR_SERVER_CERT_MISMATCH](https://answers.sap.com/questions/599994/ssslerrservercertmismatch.html)
- [Note 2124480 - ICM / Web Dispatcher: TLS Extension Server Name Indication (SNI) as client](https://launchpad.support.sap.com/#/notes/2124480)