

# Asana に対する接続
<a name="connecting-to-asana"></a>

Asana は、チームがタスクやプロジェクトを編成、計画、完了するのに役立つクラウドベースのチームコラボレーションソリューションです。Asana ユーザーの場合、アカウントにはワークスペース、プロジェクト、タスク、チームなどに関するデータが含まれます。Asana から特定の AWS サービスやその他のサポートされているアプリケーションにデータを転送できます。

**Topics**
+ [Asana の AWS Glue サポート](asana-support.md)
+ [接続を作成および使用するための API オペレーションを含むポリシー](asana-configuring-iam-permissions.md)
+ [Asana の設定](asana-configuring.md)
+ [Asana 接続の設定](asana-configuring-connections.md)
+ [Asana エンティティからの読み取り](asana-reading-from-entities.md)
+ [Asana 接続オプション](asana-connection-options.md)
+ [Asana アカウントの作成](asana-create-account.md)
+ [制限](asana-connector-limitations.md)

# Asana の AWS Glue サポート
<a name="asana-support"></a>

AWS Glue は、次のように Asana をサポートします。

**ソースとしてサポートされていますか?**  
はい。AWS Glue ETL ジョブを使用して、Asana からデータをクエリできます。

**ターゲットとしてサポートされていますか?**  
いいえ。

**サポートされている Asana API バージョン**  
 1.0 

# 接続を作成および使用するための API オペレーションを含むポリシー
<a name="asana-configuring-iam-permissions"></a>

次のサンプル ポリシーで、接続の作成と使用に必要な AWS の権限について説明します。新しいロールを作成する場合は、以下を含むポリシーを作成します。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "glue:ListConnectionTypes",
        "glue:DescribeConnectionType",
        "glue:RefreshOAuth2Tokens",
        "glue:ListEntities",
        "glue:DescribeEntity"
      ],
      "Resource": "*"
    }
  ]
}
```

------

上記の方法を使用しない場合は、代わりに次のマネージド IAM ポリシーを使用します。
+  [ AWSGlueServiceRole ](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole) – さまざまな AWS Glue プロセスを実行するために必要なリソースへのアクセス権をユーザーに代わって付与します。これらのリソースには、AWS Glue、Amazon S3、IAM、CloudWatch Logs、および Amazon EC2 が含まれます。このポリシーで指定されたリソースの命名規則に従った場合、AWS Glue プロセスは必要なアクセス許可を使用できます。このポリシーは、通常、クローラー、ジョブ、開発エンドポイントを定義するときに指定されたロールにアタッチされます。
+  [ AWSGlueConsoleFullAccess ](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AWSGlueConsoleFullAccess) — ポリシーがアタッチされているアイデンティティが AWS マネージメントコンソールを使用するときは、AWS Glue リソースへのフルアクセスを許可します。このポリシーで指定されたリソースの命名規則に従った場合、ユーザーは完全なコンソール機能を使用できます。このポリシーは、通常 AWS Glue コンソールのユーザーにアタッチされています。

# Asana の設定
<a name="asana-configuring"></a>

AWS Glue を使用して Asana から転送できるようにするには、次の要件を満たす必要があります。

## 最小要件
<a name="asana-configuring-min-requirements"></a>
+ E メールとパスワードが設定された Asana アカウントがある。アカウントの作成の詳細については、「[Asana アカウントの作成](asana-create-account.md)」を参照してください。
+ AWS Glue へのサービスアクセスで AWS アカウントを作成する必要があります。
+ Asana アカウントに次のいずれかのリソースが作成されていることを確認します。
  + `OAuth 2.0` 認証をサポートするデベロッパーアプリ。詳細については、「Asana 開発者ドキュメント」の「[OAuth](https://developers.asana.com/docs/oauth)」を参照してください。または「[Asana アカウントの作成](asana-create-account.md)」を参照してください｡ 
  + 個人アクセストークン。詳細については、「Asana 開発者ドキュメント」の「個人用アクセストークン[https://developers.asana.com/docs/personal-access-token](https://developers.asana.com/docs/personal-access-token)」を参照してください。

これらの要件を満たすと、Adobe Analytics アカウントに AWS Glue を接続する準備が整います。一般的な接続では、Adobe Analytics で他に何もする必要はありません。

# Asana 接続の設定
<a name="asana-configuring-connections"></a>

Asana は、`OAuth2` の `AUTHORIZATION_CODE` グラントタイプをサポートしています。

このグラントタイプは、ユーザーを認証するためにサードパーティーの認証サーバーにユーザーをリダイレクトすることから、「three-legged」の `OAuth` と見なされます。ユーザーは、Asana で独自の接続アプリを作成し、AWS Glue コンソールを介して接続を作成するときに独自のクライアント ID とクライアントシークレットを指定することを選択できます。このシナリオでは、引き続き Asana にリダイレクトされてログインし、リソースへアクセスするために AWS Glue を承認します。

このグラントタイプは、更新トークンとアクセストークンになります。アクセストークンの有効期間は短く、更新トークンを使用してユーザーとやり取りすることなく自動的に更新される場合があります。

`AUTHORIZATION_CODE OAuth` フロー用の接続アプリケーションの作成に関する Asana の公開ドキュメントについては、「[Asana API](https://developers.asana.com/docs/oauth)」を参照してください。

Asana 接続を設定するには:

1. AWS Secrets Manager で、次の詳細を含むシークレットを作成します。
   + カスタマーマネージド接続アプリケーションの場合 – シークレットには、`USER_MANAGED_CLIENT_APPLICATION_CLIENT_SECRET` を使用して接続されたアプリケーションのコンシューマーシークレットをキーとして含める必要があります。
   + 
**注記**  
AWS Glue で接続ごとにシークレットを作成する必要があります。

1. AWS Glue Studio で、以下の手順に従って **[データ接続]** の下に接続を作成します。

   1. **[接続タイプ]** を選択する際に、[Asana] を選択します。

   1. Asana 環境を指定します。

   1. AWS Glue が次のアクションを担い、その権限を持つことができる IAM ロールを選択します。

------
#### [ JSON ]

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "secretsmanager:DescribeSecret",
              "secretsmanager:GetSecretValue",
              "secretsmanager:PutSecretValue",
              "ec2:CreateNetworkInterface",
              "ec2:DescribeNetworkInterfaces",
              "ec2:DeleteNetworkInterface"
            ],
            "Resource": "*"
          }
        ]
      }
      ```

------

   1. AWS Glue でこの接続に使用する `secretName` を選択して、トークンを配置します。

   1.  ネットワークを使用する場合は、ネットワークオプションを選択します。

1. AWS Glue ジョブに関連付けられている IAM ロールに `secretName` を読み取るアクセス許可を付与します。

# Asana エンティティからの読み取り
<a name="asana-reading-from-entities"></a>

 **前提条件** 

読み取り元の Asana オブジェクト。使用可能なエンティティを確認するには、以下のサポートされているエンティティの表を参照してください。

 **ソースに対応するエンティティ** 


| エンティティ | フィルタリング可能 | 制限をサポートする | Order By をサポートする | Select \$1 をサポートする | パーティショニングをサポートする | 
| --- | --- | --- | --- | --- | --- | 
|  ワークスペース  | いいえ | あり | なし | あり | なし | 
| タグ | いいえ | あり | なし | あり | なし | 
| ユーザー | いいえ | あり | なし | あり | なし | 
|  ポートフォリオ  | いいえ | あり | なし | あり | なし | 
| チーム | いいえ | あり | なし | あり | なし | 
| プロジェクト | はい | あり | なし | あり | なし | 
| セクション | いいえ | あり | なし | あり | なし | 
| タスク  | はい | なし | なし | はい | はい | 
| 目標 | あり | あり | なし | あり | なし | 
|  AuditLogEvent  | あり | あり | なし | あり | なし | 
|  ステータスの更新  | あり | あり | なし | あり | なし | 
|  カスタムフィールド  | いいえ | あり | なし | あり | なし | 
|  プロジェクトの概要  | はい | なし | なし | はい | はい | 

 **例** 

```
read_read = glueContext.create_dynamic_frame.from_options(
    connection_type="Asana",
    connection_options={
        "connectionName": "connectionName",
        "ENTITY_NAME": "task/workspace:xxxx",
        "API_VERSION": "1.0",
        "PARTITION_FIELD": "created_at",
        "LOWER_BOUND": "2024-02-05T14:09:30.115Z",
        "UPPER_BOUND": "2024-06-07T13:30:00.134Z",
        "NUM_PARTITIONS": "3"
    }
```

 **Asana エンティティとフィールドの詳細** 
+ [ワークスペース](https://developers.asana.com/docs/workspaces)
+ [タグ](https://developers.asana.com/docs/tags):
+ [ユーザー](https://developers.asana.com/docs/users)
+ [ポートフォリオ](https://developers.asana.com/docs/portfolios)
+ [チーム](https://developers.asana.com/docs/teams)
+ [プロジェクト](https://developers.asana.com/docs/get-all-projects-in-a-workspace)
+ [セクション](https://developers.asana.com/docs/get-sections-in-a-project)
+ [タスク](https://developers.asana.com/docs/search-tasks-in-a-workspace) 
+ [目標](https://developers.asana.com/docs/get-goals)
+ [AuditLogEvent](https://developers.asana.com/docs/audit-log-api)
+ [ステータスの更新](https://developers.asana.com/reference/status-updates)
+ [カスタムフィールド](https://developers.asana.com/reference/custom-fields)
+ [プロジェクトの概要](https://developers.asana.com/reference/project-briefs)

 **パーティショニングクエリ** 

Spark で同時実行を使用する場合は、追加の Spark オプション `PARTITION_FIELD`、`LOWER_BOUND`、`UPPER_BOUND`、および `NUM_PARTITIONS` を指定できます。これらのパラメータを使用すると、元のクエリは Spark タスクで同時に実行できるサブクエリの `NUM_PARTITIONS` の数に分割されます。
+ `PARTITION_FIELD`: クエリのパーティション化に使用するフィールドの名前。
+ `LOWER_BOUND`: 選択したパーティションフィールドの包括的な下限値。

  日付については、Spark SQL クエリで使用される Spark の日付形式を受け入れます。有効な値の例: `2024-06-07T13:30:00.134Z`。
+ `UPPER_BOUND`: 選択したパーティションフィールドの排他的上限値。
+ `NUM_PARTITIONS`: パーティション数。

 エンティティごとのパーティション分割フィールドのサポートの詳細は、次の表にまとめられています。


| エンティティ名 | Partitioning Field | データタイプ | 
| --- | --- | --- | 
| タスク |  created\$1at  | DateTime | 
| タスク |  modified\$1at  | DateTime | 

 **例** 

```
read_read = glueContext.create_dynamic_frame.from_options(
    connection_type="Asana",
    connection_options={
        "connectionName": "connectionName",
        "ENTITY_NAME": "task/workspace:xxxx",
        "API_VERSION": "1.0",
        "PARTITION_FIELD": "created_at",
        "LOWER_BOUND": "2024-02-05T14:09:30.115Z",
        "UPPER_BOUND": "2024-06-07T13:30:00.134Z",
        "NUM_PARTITIONS": "3"
    }
```

# Asana 接続オプション
<a name="asana-connection-options"></a>

Asana の接続オプションは次のとおりです。
+  `ENTITY_NAME`(文字列) – (必須) 読み取り / 書き込みに使用されます。Asana のオブジェクトの名前。
+  `API_VERSION`(文字列) – (必須) 読み取り / 書き込みに使用されます。使用する Asana Rest API バージョン。(例: 1.0)。
+  `SELECTED_FIELDS`(List<String>) – Default: empty(SELECT \$1). 読み込みに使用されます。オブジェクトに選択する列です。
+  `FILTER_PREDICATE`(文字列) – デフォルト: 空 読み込みに使用されます。Spark SQL 形式である必要があります。
+  `QUERY`(文字列) – デフォルト: 空 読み込みに使用されます。完全な Spark SQL クエリです。
+ `PARTITION_FIELD`(文字列) - 読み取りに使用されます。クエリをパーティション化するために使用するフィールドです。
+  `LOWER_BOUND`(文字列) - 読み取りに使用されます。選択したパーティションフィールドの包括的な下限値。
+  `UPPER_BOUND` (文字列) - 読み取りに使用されます。選択したパーティションフィールドの排他的上限値。
+  `NUM_PARTITIONS`(整数) – デフォルト: 1。読み込みに使用されます。読み取り用のパーティションの数です。

# Asana アカウントの作成
<a name="asana-create-account"></a>

1. [Asana アカウント](https://asana.com/create-account)にサインアップし、**[サインアップ]** を選択します。

1. ログインすると、[アカウントのセットアップ](https://app.asana.com/0/account_setup)ページにリダイレクトされます。以下のステップを実行します。
   + アカウント設定フォームを確認します。
   + 関連するすべての詳細を入力して、Asana アカウントを作成します。
   + 情報が正しいことを再確認します。

1. **[アカウントを作成]** または **[送信]** (正確なボタンのテキストは異なる場合があります) を選択して、アカウントの設定を確定します。

**`OAuth2.0` の Asana でのアプリの作成**

1. [Asana 顧客認証情報](https://app.asana.com/-/login)を使用して Asana アカウントにログインします。

1. 右上隅にあるユーザープロファイルアイコンを選択し、ドロップダウンメニューから **[マイ設定]** を選択します。

1. **[アプリ]** タブを選択し、**[開発者アプリを管理]** を選択します。

1. **[アプリの新規作成]** を選択し、関連する詳細を入力します。

1. **[アプリを作成]** を選択します。

1. **[マイアプリ]** ページで、次の操作を行います。

   1. **[OAuth]** を選択し、**[アプリ認証情報]** セクションで、クライアント ID とクライアントシークレットを書き留めます。

   1. **[リダイレクト URL]** セクションで、必要なリダイレクト URL (複数可) を追加します。
**注記**  
次の形式を使用してリダイレクト URI を入力します: `https://{aws-region-code}.console.aws.amazon.com/gluestudio/oauth`。たとえば、米国東部 (バージニア北部) の場合は次を使用します: `https://us-east-1.console.aws.amazon.com/gluestudio/oauth`

**Asana での `PAT` トークン用アプリの作成**

1. [Asana 顧客認証情報](https://app.asana.com/-/login)を使用して Asana アカウントにログインします。

1. 右上隅のユーザープロファイルアイコンを選択し、ドロップダウンメニューから **[マイプロファイル設定]** を選択します。

1. **[アプリ]** タブを選択し、**[サービスアカウント]** を選択します。

1. **[アプリの新規作成]** を選択し、関連する詳細を入力します。

1. **[サービスアカウントを追加]** を選択します。

1. 次のページにはトークンが表示されます。トークンをコピーして安全に保管します。
**重要**  
このトークンは 1 回だけ表示されます。必ずコピーして安全に保管してください。

# 制限
<a name="asana-connector-limitations"></a>

Asana コネクタの制限は次のとおりです:
+ エンタープライズドメインのサービスアカウントは、監査ログ API エンドポイントにのみアクセスできます。これらのエンドポイントにアクセスするには、サービスアカウントの個人アクセストークンによる認証が必要です。
+ Goal エンティティは、Premium プラン以上のユーザーアカウントでのみアクセスできます。
+ `Audit Log Event Entity` – コネクタでは、`start_at` フィールドと `end_at` フィールドが 1 つのフィールド「start\$1end\$1at」に結合され、フィルタリングと増分転送をサポートします。
+ パーティショニングは、大なりイコール演算子と小なりイコール演算子をサポートしている場合でも、`Date` フィールドではサポートできません。シナリオ: `partitionField` を `due_on` (データ型: 日付)、`lowerBound` を `2019-09-14`、`upperBound` を `2019-09-16`、`numPartition` を `2` としてジョブを作成しました。エンドポイント URL のフィルター部分は次のように作成されます。
  + partition1: due\$1on.before=2019-09-14&due\$1on.after=2019-09-14
  + partition2: due\$1on.before=2019-09-15&due\$1on.after=2019-09-15 出力:
  + partition1 では、due\$1date が 2019-09-14 および 2019-09-15 のデータを取得します。
  + partition2 では、due\$1date が (partition1 にあった) 2019-09-15 と同じデータが他のデータとともに取得され、データの重複が発生します。
+ SaaS エンドから不正なリクエストエラーがスローされるため、同じフィールドでフィルタリングとパーティショニングをサポートすることはできません。
+ Task エンティティには、フィルター条件に少なくとも 1 つのフィールドが必要です。Asana には、時間ベースのフィールドに基づいてレコードをソートしないとページ分割が識別されないという制限があります。したがって、Created\$1at field は、次のレコードセットを区別するためにページ分割とともに使用されます。Created\$1at field はフィルターで必須としてマークされ、指定されていない場合、デフォルト値は 2000-01-01T00:00:00Z です。ページ分割の詳細については、「[ワークスペースのタスク](https://developers.asana.com/reference/searchtasksforworkspace)」を参照してください。