# MuleSoft Training: 20Sep2022DevelopmentFundentals
###### tags: `MuleSoftTraining`
[TOC]
Anypoint Platform 開発基礎コース(5日間)にようこそ!
## モジュール0: トレーニングの準備
[開発:基礎コース セットアップマニュアル](
https://salesforce.quip.com/hhk2ABFZZawE)
- [ ] 1. training.mulesoft.com からファイルのダウンロード
- XXX_studentManual_XXX.pdf(受講者マニュアル) // 復習用
- :star: XXX **_studentFiles_** XXX.zip (受講者ファイル) // *このファイルを最も使用します!*
- (5日間)APDevFundamentals4.4_studentFiles_xxx.zip
- XXX_studentSlides_JA_XXX.zip(受講者スライド)// 復習用
- [ ] 2. [Anypoint Platform アカウント
](https://salesforce.quip.com/QQN7Acqju0il)
- ※ユーザー名とパスワードをお忘れなく!
- ※アカウントには有効期限があります。必ずコースの直前に作成してください。
- [ ] 3. [Anypoint Studio](https://www.mulesoft.com/lp/dl/studio)
- [起動確認](https://salesforce.quip.com/tTDHAkFqrNb2)
- [トラブルシューティング](https://salesforce.quip.com/n2iFAKKHMM1A)
- [ ] 4. [Adavanced REST Client](http://install.advancedrestclient.com/install)
- [Postman](https://www.postman.com/downloads/) などももちろんOKです!
- [ ] 5. [Salesforce開発者アカウント](https://salesforce.quip.com/U8mfAzhdbDOq#WfLAAA7PY1C)
- 5日間参加する方のみ必要です! (3日目に再度ご案内します)
- [ ] 6. [VMの接続(事前に用意を依頼された方のみ)](https://use.cloudshare.com/Class/ahpcb)
- Username : ご自身のメールアドレス
- Password:メールで別途送信
## モジュール1 API 主導の接続性 (API-led Connectivity)
### 今日の課題
- IT に求められている変化の量とスピードに、対応することができない (時間・人員・コストの制約 etc..)
- イノベーションを起こすための足枷に
- 求められる変化の量・スピードは、これらも多く・速くなっていくことが予想されている
そこで MuleSoft は *IT 資産 (アセット) の再利用* に着目した運用モデルを提案 >
### :star:API主導の接続性(API-led Connectivity)

- *再利用*にフォーカスを置いた、3階層に分けた API 設計の考え方(MVCの考え方に近い)
- それぞれの API は、マイクロサービスとして独立しているため、セキュリティや保護、機能追加の観点から管理がしやすい
#### エクスペリエンスAPI層
- API クライアント (呼び出し元) に応じた違いを吸収する (データ型、データのフォーマット、セキュリティ etc..)
#### プロセスAPI層
- ビジネスロジック: システム API や他のプロセス API からのデータを処理する
#### システムAPI層
- システムからデータを取得する、システムのデータを更新するなど、バックエンドシステムと繋がるAPI
- 必要に応じて、プロセスAPIで処理がしやすいように、統一のデータ型 (CDM) への変換を行う。
- 例:) 「Salesforceの顧客情報」と「SAPの顧客情報」 のフィールド名、カラム名、データ型を統一
- プロセスAPIの肥大化を防ぎ、システムAPIはより再利用がしやすくなる
### C4E (Center for Enablement)
Anypoint Platform をより活用し、アセット (資産) の *再利用* を促進するためのチーム作り
### API
- REST API / RESTful API
- HTTP
- HTTPメソッド:GET/PUT/POST
- JSON/HTTP
- URI:リソース
- SOAP API
- AWS API Gateway
- 連携、受け皿
- Twitter API
- Slack API
- Google Map
- Google
### REST(ful) API とは?
キーワード: JSON (XML), HTTP, URL(URI)に "リソース名" が含まれる
- GET: /companies
- GET: /companies?location=FR&industory=retail
- ? や &: *クエリパラメータ*。主にフィルタリングに使用する
- GET: /companies/3
- 3: *URIパラメータ*「ID が "3" の会社情報だけ欲しい」
- POST: /companies
- データの作成
- PUT: /companies/3
- データの更新
### MLB REST API (https://api.mlb.com)(架空)
- GET:/teams
- 全ての MLB のチーム
- GET:/teams?state=CA
- カリフォルニアにあるチーム
- GET:/teams/24(/teams/{teamId})
- エンゼルス!
- GET: /teams/24/players/409 (/teams/{teamId}/players/{palyerId})
- 大谷選手!
- GET: /teams/24/players?position=picther (/teams/{teamId}/players)
- エンゼルスのピッチャー
- GET: /teams/24/players?position=picther&position2=outfielder
- 大谷選手!
### JSON
JSON: キー/バリューペア
```
{
"age": 31,
"first_name": "Aaron"
}
```
{ } - オブジェクト
[ ] - 配列
リテラル: String, Null, Number, Boolean...
application/JSON
```
{
"firstname": "Shohei",
"lastname": "Ohtani",
"ID": 409,
"playerNo": 17,
"nationality": "JP",
"position": ["picther", "outfielder" ],
"salary": 3000000,
"age": 27,
"isMarried": false
}
```
### HTTP ステータスコード
2XX:
- 200: OK
- 201: Created (データが作成された)
4XX:
- 400: BAD REQUEST
- 403: Forbitten
- 404: NOT FOUND
5XX:
- 500: Server Side Error
- 503: Service Unavailable
#### HTTPステータスコード関連資料
- https://http.cat/
- https://httpstatusdogs.com/
### American Flights API
1. 保護されていない API
- 実装 URL
- GET: http://training4-american-ws.cloudhub.io/api/flights
2. 保護されている API (Id/Secret の認証情報 + レート制限)
- プロキシURL
- http://training4-american-api.us-e1.cloudhub.io/flights
- 認証情報
- client_id : `d846d01ea59640108779eaaa532d00ca`
- client_secret: `F7C5ecA48EBA449399b4B140416849B0`


Q. enum - SFO, LAX, CLE とは
A. enum は「列挙型」で、「このうちのどれかを受け付ける」という意味になります。今回のAmerican APIでは「SFO」「LAX」「CLE」の3つの「destination(行先)」から、パラメータを指定できます。
※指定が必須ではないため、指定しなければ全ての行先を含むフライト情報が返されます。
## モジュール2: Anypoint Platform の概要
### Catalyst (Knowledgehub)
ベストプラクティスを集めたレポジトリ
- https://knowledgehub.mulesoft.com/s/
- [日本語] https://knowledgehub.mulesoft.com/s/global-search/%40uri#q=JP&sort=relevancy
- [翻訳ツール] https://www.deepl.com/ja/translator
### Exchange
- アセット(資産)を公開し、社内(時には社外)に共有するためのレポジトリ
- REST API, テンプレート, サンプル、API 仕様を作成するためのフラグメント etc...
### Design Center
1. API Deigner
API を "設計" するツール (仕様)
2. Flow Designer
API を開発する Web ツール (Anypoint Studio で開発する機会の方が断然多いか?)
### Mule アプリケーション
- Java ベース
- 各Mule アプリケーションは、XML として管理される
- jar ファイルとしてパッケージ化
- Mule ランタイムが、アプリケーション(jar)を実行
- 複数のフローで構成される
ホスト: training4-american-api.us-e1.cloudhub.io
ポート: 80
プロトコル: HTTP
## モジュール3: API の設計
Anypoint Platform > Design Center >**API Designer** を使用して API を設計する
### REST API を設計するための言語 (ツール)
- RAML 1.0
- https://raml.org/
- https://github.com/raml-org/raml-spec/blob/master/versions/raml-10/raml-10.md/
- OAS 2.0 (Swagger) / 3.0
### Spec-Driven Development (仕様駆動型開発)
なぜ?
- その API の役割や機能について合意をとる
- フィードバックをもらって改善する
- データ型、エンドポイント名、フィールド名、パラメータ (必須 or not)、などについての事前確認
- 仕様通りのバリデーションを自動適用
- Studio にインポートして、土台となるスケルトン (インタフェースフロー)を自動で生成する
- Exchange に公開したタイミングで
- API ポータルが自動生成される
- API コンソールが自動生成される
- モッキングサービスが自動生成される
- MS2-Delay, MS2-Example
- [シミュレーションヘッダー(動作ヘッダー)](https://docs.mulesoft.com/jp/design-center/apid-behavioral-headers) により実際に近いモック呼び出しが可能
- コネクタの自動生成 (REST Connect)
### Versioning (バージョン管理)
Semantic Verrsioning (セマンティックバージョニング)
X.Y.Z (1.0.0)
X = Major Version - 後方互換性が保たれない大きな変更
1.2.1 vs 2.0.0
Y = Minor Version - 機能追加など、後方互換性が保たれる範囲での変更
1.2.1 vs 1.3.0
Z = Patch Version - バグ修正など、軽微な変更
1.2.1 vs 1.2.2
### AmericanFlights SAPI RAML (Sample)
```
#%RAML 1.0
title: American Flights SAPI
types: #データ型の定義
AmericanFlight: !include exchange_modules/68ef9520-24e9-4cf2-b2f5-620025690913/training-american-flight-data-type/1.0.1/AmericanFlightDataType.raml
/flights:
get:
displayName: getFlights(フライト情報の取得)
description: アメリカン航空のフライト情報を取得する
queryParameters:
destination?:
# #でコメントを残せます。
# ? = required: false
description: 目的地でフィルタリングするためのクエリパラメータ
enum:
- SFO
- CLE
- LAX
responses: # レスポンス
200: # OK
body:
application/json:
# !include -> 外部のramlを参照する
example: !include exchange_modules/68ef9520-24e9-4cf2-b2f5-620025690913/training-american-flights-example/1.0.1/AmericanFlightsExample.raml
type: AmericanFlight[] # [] = 配列
post:
displayName: createFlight(フライト情報の作成)
description: アメリカン航空のフライト情報を作成する
body: # リクエストボディ
application/json:
type: AmericanFlight
example: !include examples/AmericanFlightNoIDExample.raml
responses: # レスポンス
201: # Created
body:
application/json:
example:
message: flight has been added!(but not really... でも本当は追加していない..)
/{ID}: # {}は動的に変わるURIパラメータを示しています
get:
displayName: getFlightById(IDを使用して、フライト情報の取得)
responses:
200:
body:
application/json:
type: AmericanFlight
example: !include examples/AmericanFlightExample.raml
```
### Public portal

## モジュール4 API の開発
### Mule アプリケーションとは
- フロー (flow) の集合体
- Java ベースのアプリケーション
- XMLでコードが生成される
- DataWeave や XML を触る際には、コーディングを行う場合もあるが、基本的にはローコードで開発を進めることが可能
- Mule ランタイムエンジンが、jarファイルとしてパッケージ(Maven)されたMuleアプリケーションを実行する
### フロー(flow) とは

- 関数やメソッドのように、意味のある単位で分けられた、再利用・再呼び出し可能なスコープ
- Mule アプリケーションは、複数のフローで成り立っている
- HTTP Listner のようにフローが開始されるトリガーを「イベントソース」、それ以外 (Transform Message, DB Select, Set Payload...) を「イベントプロセッサ」と呼んでいる
- フローが呼び出されるタイミングで、Mule イベントが生成される
### Mule Event とは
Mule アプリケーションが、フロー内で扱うデータオブジェクト (Java オブジェクト)
- Mule Event
- Mule Message
- Attributes (属性: データの付随情報 (クエリパラメータ、ヘッダー、URI パラメータ))
- GET:/customers?id=48493
- `#[attributes.queryParams.id]` >>> 48493
- GET:/customers/48493
- `#[attributes.uriParams.id]` >>> 48493
- `#[attributes.headers.method]` >>> POST, GET, PUT
- Payload (ペイロード: データの本体)
- `#[payload]` >>> "hello world!"
- `#[payload.year]` >>> 2020
- vars (variables, 変数)
- `#[vars.hogeFlag]` >>> true
- `#[vars.tranId]` >>> 41674810
- `#[vars.theResult]`

### Anypoint Studio: jar ファイルのインポート方法
1. Anypoint Studio > 画面左側 (ファイルエクスプローラー) > 右クリック > Import
2. "mule" と検索して、 ”packaed mule applications (jar)” を選択
3. インポートする jar を選択
### Training DB(MySQL)の接続情報
```
ホスト: iltdb.learn.mulesoft.com
ポート: 3306
ユーザー: mule
パスワード: mule
データベース: training
```
### Transform Message
```
%dw 2.0
output application/json
---
payload
```
### Tooling Instance が止まってしまう
- 主な原因: マシンのスペック
- RAM 8GB以上(16GB だとおそらく起きない)
- CPU 2.0Ghz以上
- 主な解決策: マシンのスペックが上記を満たしているのであれば、Anypoint Studio とマシンの再起動をお試しください。

`application/csv`
```
ID,code,price,departureDate,origin,destination,emptySeats
1,rree0001,541,2016-01-20T09:00:00,MUA,LAX,0
2,eefd0123,300,2016-01-25T09:00:00,MUA,CLE,7
3,ffee0192,300,2016-01-20T09:00:00,MUA,LAX,0
4,rree1000,200,2016-01-20T09:00:00,MUA,CLE,5
5,rree1093,142,2016-02-11T09:00:00,MUA,SFO,1
6,ffee1112,954,2016-01-20T09:00:00,MUA,CLE,100
7,eefd1994,676,2016-01-01T09:00:00,MUA,SFO,0
8,ffee2000,300,2016-02-20T09:00:00,MUA,SFO,30
9,eefd3000,900,2016-02-01T09:00:00,MUA,SFO,0
10,eefd4511,900,2016-01-15T09:00:00,MUA,LAX,100
11,rree4567,456,2016-01-20T09:00:00,MUA,SFO,100
```
## モジュール5 API のデプロイ・保護・管理
### Mule アプリケーションのデプロイ環境 (ランタイムプレーン)
- CloudHub
- MuleSoftがホストする Mule ランタイム実行環境
- CloudHub ワーカーというクラウド上の仮想マシンで、Mule ランタイムをホストし、そこで Mule アプリケーションを実行する
- 内部的に AWS を使用 (CloudHub ワーカーは、AWS 上の VM (EC2 インスタンス))
- 管理のリソースを最小に抑えることができる(多くの部分を MuleSoft が管理)
- Customer-hosted Mule ランタイム
- お客様のデータセンター、オンプレミス、プライベートクラウド (AWS, Azure, GCP)で実行する
- 設定に柔軟性がある分、お客様が管理・設定することが多い
- Runtime Fabric (RTF)
- Docker, kubernates を用いた Mule ランタイム実行環境
- k8s の実行インフラはお客様が用意・管理
- Docker イメージや k8s クラスタを構成するためのスクリプトは MuleSoftが提供
- 2種類の RTF
- RTF VM
- AWS, Azure, オンプレミス etc ,,
- RTF on Self-managed k8s (自社管理のkubernatesでホストする RTF)
- EKS, AKS, GKE などの管理型 kubernates サービス
### Runtime Manager
- Mule アプリケーションのデプロイやMuleランタイムの管理を行う
### API Manager
- API を保護するためのポリシーやプロキシの設定・管理を行う
### API Proxy
- 実装を保護するためのアプリケーション
下記の2種類の方法

1. Proxy with Endpoint
- 今回のコースで扱った方法
- 実装アプリケーションとは別のアプリケーション(Proxy アプリケーション)を作成・管理
- 実装の URL とは、別の URL が存在する
API クライアント -> Proxy URL > 実装 URL
2. Basic Endpoint
- 実装アプリケーションの内部で、APIの保護ポリシーを実行する
### Endpoint with Proxy (プロキシアプリケーション + 実装アプリケーション)
+ Mule/ non-Mule アプリケーションのどちらもサポート + 「API 実装」 と 「セキュリティ / ポリシー」 との クリアな分離
+ Anypoint Studio 上で 「Autodiscovery Config 設定」をする必要がない
- 追加のリソースが必要 (API Proxy アプリケーションのデプロイ, $$$)
- 管理する App の増加
- そのままでは バイパス可能? -> API 実装 URL に直接アクセスできないよう、考慮が必要
- 通過するアプリケーションが増える -> latency が高くなる ?
### Basic Endpoint (実装一体型プロキシ)
+ URLが 1つ (実装URL = プロキシ URL) なので、簡単にバイパスすることができない
+ 追加の vCore を使わない ($$$)
+ 別アプリケーションに通信する必要がない -> 追加の latency 生じさせる場所が少ない
+ プロキシ アプリケーションをわざわざ別で管理する必要がない
- non-Mule アプリケーション のサポートなし- Anypoint Studio 上で 「Autodiscovery Config 設定」をする必要あり
### Gate Keeper
https://docs.mulesoft.com/jp/api-manager/2.x/gatekeeper
### オンプレ Proxy アプリケーションのためのプロキシ設定
Configuring API Gateway to Point to a Proxy
https://docs.mulesoft.com/api-manager/1.x/configuring-proxy-access-to-an-api
### RAML Sample with Client Auth
```
#%RAML 1.0
title: American Flights SAPI
traits: #特性
client-id-required:
description: ヘッダーに client_id と client_secret が必須。Exchange > 各ページの3点ボタンから 「Request Access」 で権限を申請してください。
headers:
client_id:
type: string
client_secret:
type: string
responses:
401:
description: Unauthorized, The client_id or client_secret are not valid or the client does not have access.
429:
description: The client used all of its request quota for the current period.
500:
description: An error occurred, see the specific message (Only if it is a WSDL endpoint).
503:
description: Contracts Information Unreachable.
types: # データ型の宣言
AmericanFlight: !include exchange_modules/68ef9520-24e9-4cf2-b2f5-620025690913/training-american-flight-data-type/1.0.1/AmericanFlightDataType.raml
/flights:
is:
- client-id-required
get:
displayName: getFlgihts (フライト情報の取得)
queryParameters:
destination?: # '?' >>> required: false と同等。
description: 行先(destination)に応じて、フライト情報をフィルタリングする
enum: #列挙型
- SFO
- LAX
- CLE
responses: #レスポンス
200: #OK
body:
application/json:
type: AmericanFlight[] # [] = 配列
example: !include exchange_modules/68ef9520-24e9-4cf2-b2f5-620025690913/training-american-flights-example/1.0.1/AmericanFlightsExample.raml
post:
displayName: postFlgihts (フライト情報の作成)
/{ID}:
is:
- client-id-required
get:
displayName: getFlgihtsByID (ID を指定したフライト情報の取得)
responses: #レスポンス
200: #OK
body:
application/json:
type: AmericanFlight
example: !include examples/AmericanFlightExample.raml
```

Consumer:http://training-american-flights-sapi-yoshida.us-e2.cloudhub.io
Implementation URL:http://training-american-flights-sapi-yoshida.us-e2.cloudhub.io/api
## モジュール6 Mule Event

### Set Payload
Mule Event > Mule Message の payload (データの本体・本文) を設定するために使用するプロセッサ
### HTTP コネクタ > HTTP Request オペレーション
HTTP プロトコルを使用した通信を行う
### Set Variable
Mule Event > Variable
### DataWeave Playground
https://developer.mulesoft.com/learn/dataweave/
### 空の Logger
```
{
payload=hello world!
mediaType=application/java; charset=UTF-8
attributes=org.mule.extension.http.api.HttpRequestAttributes
{
Request path=/hello
Raw request path=/hello
Method=GET
Listener path=/hello
Local Address=/127.0.0.1:8081
Query String=
Relative Path=/hello
Masked Request Path=null
Remote Address=/127.0.0.1:53645
Request Uri=/hello
Raw request Uri=/hello
Scheme=http
Version=HTTP/1.1
Headers=[
host=localhost:8081
]
Query Parameters=[]
URI Parameters=[]
}
attributesMediaType=*/*
}
```
### Connection idle timeout vs Response timeout
* Connection idle timeout (返すエラー:connection closed)
* HTTPやTCPのConnectionが成立している場合、アクセスがなくてもConnectionを有効に維持するための最大の時間
* Mule Default : 30秒
* Response timeout (返すエラー:timeout exceeded)
* Responseを待つための最大の時間
* Mule Default : 10秒
* Reference : https://docs.mulesoft.com/jp/http-connector/1.5/http-documentation
## モジュール7 プロジェクト
### Maven
Java のアプリケーションのパッケージ、依存関係の管理
https://maven3.kengo-toda.jp/primer
### global.xml
コネクタの設定など、共通の設定は別xmlに切り出す
### yaml
config.yaml (dev-config.yaml, prod-config.yaml)
> 設定を一箇所にまとめる + 環境ごとに切り替える
## モジュール8 様々な Web Service の呼び出し
### United
REST API > HTTP Request オペレーション
### Delta
SOAP API > Web Service Consumer
### American
- REST API + Connector > American Fights SAPI コネクタ!!!
(API 仕様から自動生成)
- インポートするだけでコンシュームできたので一番楽だった。→ 再利用促進の観点でExchangeにアセットが多ければ多いほど開発速度が速くなることが考えられる。
## モジュール9 ルーター
### *Choice*
if, else if, else..
### *Scather-Gather*
非同期・マルチスレッド、全てのルートを実行する
### FIrst Successful
成功したら次のプロセッサへ
失敗したら次のルートを試行する
### Round Robin
順番に各ルートを実行
### Validation モジュール
検証のためのモジュール。失敗したらエラーをスロー
## モジュール 10: エラー処理
### エラーハンドラのスコープ

0. Mule デフォルトエラーハンドラ
- カスタマイズ不可
1. **アプリケーション(グローバルエラーハンドラ)**
- *エラーハンドラが設定されていない時に限り*、実行されるバックアップ用エラーハンドラ
2. **フローレベル** のエラーハンドラ
- 設定されたフローで起きたエラーを処理
3. **プロセッサレベル** のエラーハンドラ
- Try スコープで設定された範囲で起きたエラーを処理
### エラーハンドラの種類
1. On Error Propagate
- エラーを伝播する (エラーが起きた際に、エラーを再スローする)
2. On Error Continue
- エラーを伝播しない (エラーが起きた際に、エラーを再スローせずに飲み込む)
### Error Object
- Mule Event
- Message
- attributes
- payload
- Variables
エラーが発生した時だけ、Error のオブジェクトが生成される
- **Error** (エラーオブジェクト)
- _errorType_ (HTTP:NOT_FOUND, HTTP:BAD_REQUEST) \<Object\>
- _namespace_ (名前空間) \<String\>
- HTTP, VALIDATION etc
- _identifier_ (識別子) \<String\>
- NOT_FOUND, BAD_REQUEST
- _description_ \<String\>
- エラーの詳細

## Module 11 Dataweave
Input : https://hackmd.io/N8vxAI3hS1GPyUeWBCW-PA?view
```
%dw 2.0
// output application/json
output application/json
// import * from custom
import getSeatNum from custom
import daysBetween from dw::extension::DataFormat
---
// actual logic
// sizeOf(payload)
// payload[7].airlineName
// data: payload
// payload
// payload[-2]
// {
// flight1: payload[0]
// }
// Single Value Selector
// payload.price
// Multi Value Selector
// payload.*price
// Decendent Value Selector
// payload..*price
// [
// 1, 2, 3
// ]
// payload map {
// // $, $$
// // $ = item, $$ = index
// flightCode: $.flightCode,
// airlineName: $.airlineName,
// ("flight_" ++ $$): $$
// }
// payload map(item, index) -> {
// flightCode: item.flightCode,
// airlineName: item.airlineName
// }
// root: {(
// payload map {
// flight: $
// }
// )}
// json to xml (親が必要となる)
// 属性をつけるときは、@で。
// root: {(
// payload map {
// flights @("index": $$): {
// flight: $
// }
// }
// )}
// payload..*return map {
// flight: $
// }
// var, fun etc.
// seatNum
// typeOf(seatNum)
getSeatNum('777')
```
```
%dw 2.0
output application/json
fun getSalesConfirmation(price: Number): String = if (price < 500) 'Sales' else 'Normal'
---
{
price: payload.price,
result: getSalesConfirmation(payload.price)
}
```
<下記は参考用です。Playgroundで試してみてください。>
```
%dw 2.0
/** 関数の宣言 その1*/
fun addNumbers(a:Number,b:Number):Number = a+b
/** 関数の宣言 その2*/
var addNumbers2 = (a,b) -> a+b
/** カスタムのデータ型 Currency*/
type Currency = String {format: ",###"}
// 10000000 as Currency => 10,000,000
/** カスタムのデータ型 日付*/
type CustomDate = Date {format: 'dd-MM-YYYY'}
// now() as CustomDate > "21-01-2022"
type CustomDate2 = Date {format: 'dd-MMM-YYYY'}
// now() as CustomDate > "21-Jan-2022"
/** CSV のオプション*/
// output application/csv
// header=false,separator='\n' // TSV
/** 出力フォーマット */
/** 外部モジュールの import */
// dw::core::Dates https://docs.mulesoft.com/dataweave/2.4/dw-dates
// 1. import tomorrow from dw::core::Dates
// 2. import * from dw::core::Dates
// 3. import dw::core::Dates + Dates::tomorrow()
// 4. import なし + dw::core::Dates::tomorrow()
// カスタムモジュール https://docs.mulesoft.com/dataweave/2.4/dataweave-create-module
output json
---
dw::core::Dates::tomorrow()
// 以下ノート!!
/** typeOf 型のチェック */
// typeOf(payload)
/** 配列の最後の要素を取得 */
// payload[-1]
/** 配列の filter & orderBy*/
// payload
// filter $.emptySeats >= 1 // 予約可能なもののみフィルター
// orderBy ((item, index) -> item.emptySeats) // 残り座席数の昇順でソート
/** 配列のマッピング map function version 1*/
// $ -> each item, $$ -> index
// payload map {
// airline: $.airline,
// code: $.flightCode,
// price: $.price
// }
/** 配列のマッピング map function version 2*/
// payload map (item, idx) -> {
// airline: item.airline,
// code: item.flightCode,
// price: item.price,
// index: idx
//}
/** 型の変換 as Number, as String*/
// payload..price map
// $ as String {"format": "###.0"} as Number// 型の強制
/** Array -> XML */
// flights: { // ルート
// flight : payload // 個別の繰り返し用のタグ + 配列の各要素
// }
/** JSON => XML: @アトリビュートに対応します */
// flights : {
// flight: payload map {
// airline: $.airline,
// flightCode @(totalSeats:$.totalSeats default -1): $.flightCode
// }
// }
/** XML => JSON: @アトリビュートに対応します その2*/
// payload..*flight map {
// airline: $.airline,
// flightCode: $.flightCode,
// totalSeats: $.flightCode.@totalSeats
// }
/** map function for XML {(...)}*/
// flgihts: {(
// payload map {
// // $$ => index
// 'flight$($$)': {
// airline: $.airline,
// price: $.price,
// '$($.flightCode default '')': $.departureDate
// }
// }
/** dataweave 関数の引数の渡し方 */
// https://docs.mulesoft.com/dataweave/2.4/dw-core-functions-contains
// その1
// [1,2,3,4,5] contains (1) // >>> true
// その2
// contains([1,2,3,4,5], 1) // >>> true
/** lookup > DW からフローを呼び出す*/
{
// lookup(関数名, payload)
americanFlightsResult: lookup('getAmericanFlights', {})
}
```
## Module 12 コレクションの処理
### File コネクタ
File, FTP, SFTP, FTPS (S3, Googel Drive などもある)
>> On New or Updated File でフローを開始 (決まった間隔 or Cron )
### On Table Row (Databae コネクタ)
1 行ずつ新しい DB 行を取得 (決まった間隔 or Cron )
### Scheduler
決まった間隔 or Cron
### Object Store
Key-Vakue ペアのストレージ (memory or disk)
** デプロイ環境によって異なる! e.g. Object Store V2 on CloudHub
### JMSコネクタ
ブローカー, Queue, Pub-Sub
### JMS vs VM
JMS: 広いユースケース (pub-sub, アプリケーション間のコミュニケーション)
VM: 手軽, 同一アプリケーション内のコミュニケーション(Muleドメインプロジェクトを除く)
## Module 13 コレクションの処理
### For Each
- シングルスレッド
- 同期処理
- sequential (順番に) 処理を行う
- batch block size (デフォルト 1)
- [1,2,3,4,5] >>> 1 -> 2 -> 3 -> 4 -> 5
- batch block size (2)
- [1,2,3,4,5] >>> 1,2 -> 3,4 -> 5
- For Each スコープの中で、payload を書き換えても (e.g. Set Payload)、**For Each スコープを終えれば、payload はスコープに入る前の元々のデータを保持し続ける**
- 変数は、全てのループで共有される
- For Each スコープの前で宣言された変数も、For Each スコープ内で参照・変更・削除可能
### Batch Job

- マルチスレッド
- 非同期処理
- parallell(並列に)処理を行う
- 変数は、各レコードに固有のもの
- レコード1 `#[vars.hoge = true]`
- (レコード1 の `#[vars.hoge]`は、そのまま BatchStep A, B, C で参照・変更可能)
- レコード2 ``#[vars.hoge = false]`
- (レコード2 の `#[vars.hoge]` は、そのまま BatchStep A, B, C で参照・変更可能)
- Batch Step
- Batch Jobの処理の単位
- Batch Jobは1つ以上のBatch Stepで構成されている
- それぞれの Step は、それぞれの条件に基づいて、レコードを受け入れる (acceptPolicy, acceptExpression)
- e.g. acceptExpression: `#[vars.hogeFlag==true]`
acceptPolicy: `ONLY_FAILURES` (処理に失敗したレコードだけを処理する Batch Step)
- Batch Aggregator
- Bulk Insert など、まとめて処理を行う
- 2種類の設定
1. Fixed Size (固有のサイズ)
2. Streaming
- maxFailedRecords
- 失敗したレコードを許容する数 (デフォルト 0)
- batchBlockSize
- 各スレッドがどのくらいの単位で、各レコードをまとめて処理するか (デフォルト100)
e.g. 1000 レコード -> batch block size == 100
- 1-100(100単位)
- 101-200(100単位)
- 201-300(100単位)
...
- 901-1000(100単位)
もし、batch block size が1で、4つのレコードを処理する場合...

- onComplete フェーズで、payloadはサマリーレポートに置き換わる
```
{
"onCompletePhaseException": null,
"loadingPhaseException": null,
"totalRecords": 2000,
"elapsedTimeInMillis": 8909,
"failedOnCompletePhase": false,
"failedRecords": 1,
"loadedRecords": 2000,
"failedOnInputPhase": false,
"successfulRecords": 1999,
"inputPhaseException": null,
"processedRecords": 2000,
"failedOnLoadingPhase": false,
"batchJobInstanceId": "9d6a7e50-5bd0-11ec-8902-a483e7ab0cd9"
}
```
※変数は、各 Batch Step を超えて参照・変更ができる
※Batch Job スコープの完了後は、各変数を参照することはできない