JavaベースのCAPプロジェクトをMTAでデプロイする

## 目的
JavaベースのCAPプロジェクトをMTAでデプロイする方法について確認します。

## 背景
CAPの[チュートリアル](https://developers.sap.com/mission.cap-java-app.html)では、manifest.ymlを使用してサービス部分のみデプロイする方法が紹介されていました。しかし、移送を考えるとDBモジュールやその他のサービスインスタンスも同時にデプロイできるよう、MTAを使ったほうがよいです。

"cap java mta"などで検索すると、以下の記事やGitHubリポジトリがありました。
- https://blogs.sap.com/2023/09/06/deploy-a-java-based-cap-with-frontend-into-btp/
- https://github.com/SAP-samples/cloud-cap-samples-java/tree/main

これらの記事にはmta.yamlファイルの設定については書かれているものの、mta.yamlをどうやって作成するかについては書かれていませんでした。Node.jsだと`cds add mta`により自動的に必要な設定が入ったmta.yamlを作成してくれますが、Javaのプロジェクトでも同様に手順で作成できるかがわかりませんでした。

## 結論
JavaのプロジェクトでもNode.jsと同様に、`cds add mta`コマンドでmta.yamlの作成およびデプロイが可能です。

参考
- Javaのプロジェクト生成方法：[Java / Getting Started](https://cap.cloud.sap/docs/java/getting-started#run-the-cap-java-maven-archetype)
- ビルド、デプロイ方法：[Deployment / Deploy to  Cloud Foundry](https://cap.cloud.sap/docs/guides/deployment/to-cf)

## 手順

### 1. プロジェクトを生成

```
cds init <PROJECT-ROOT> --add java
```

### 2. サンプルデータモデルを追加

```
mvn com.sap.cds:cds-maven-plugin:addSample
```
または
```
cds add tiny-sample
```

### 3. Cloud Foundryをターゲットプラットフォームに追加

```
mvn com.sap.cds:cds-maven-plugin:addTargetPlatform -DtargetPlatform=cloudfoundry
```

### 4. HANA Databaseを使用する設定を追加

```
cds add hana --for production
```

### 5. XSUAAを使用した認証を追加

```
cds add xsuaa --for production
```
### 6. mta.yamlを追加

```
cds add mta
```
以下の内容でmta.yamlが生成されます。

```yaml
_schema-version: '3.1'
ID: java-mta
version: 1.0.0-SNAPSHOT
description: "A simple CAP project."
parameters:
  enable-parallel-deployments: true
modules:
  - name: java-mta-srv
    type: java
    path: srv
    parameters:
      buildpack: sap_java_buildpack
    properties:
      SPRING_PROFILES_ACTIVE: cloud,sandbox
      JBP_CONFIG_COMPONENTS: "jres: ['com.sap.xs.java.buildpack.jre.SAPMachineJRE']"
      JBP_CONFIG_SAP_MACHINE_JRE: '{ use_offline_repository: false, version: 17.+ }'
    build-parameters:
      builder: custom
      commands:
        - mvn clean package -DskipTests=true
      build-result: target/*-exec.jar
    provides:
      - name: srv-api # required by consumers of CAP services (e.g. approuter)
        properties:
          srv-url: ${default-url}
    requires:
      - name: java-mta-auth
      - name: java-mta-db
      - name: app-api
        properties:
          CDS_MULTITENANCY_APPUI_URL: ~{url}

  - name: java-mta-db-deployer
    type: hdb
    path: db
    parameters:
      buildpack: nodejs_buildpack
    build-parameters:
      builder: custom
      commands:
        - npm run build
    requires:
      - name: java-mta-db

  - name: java-mta
    type: approuter.nodejs
    path: app/
    parameters:
      keep-existing-routes: true
      disk-quota: 256M
      memory: 256M
    requires:
      - name: srv-api
        group: destinations
        properties:
          name: srv-api # must be used in xs-app.json as well
          url: ~{srv-url}
          forwardAuthToken: true
      - name: java-mta-auth
    provides:
      - name: app-api
        properties:
          url: ${default-url}

resources:
  - name: java-mta-auth
    type: org.cloudfoundry.managed-service
    parameters:
      service: xsuaa
      service-plan: application
      path: ./xs-security.json
      config:
        xsappname: java-mta-${org}-${space}
        tenant-mode: dedicated
  - name: java-mta-db
    type: com.sap.xs.hdi-container
    parameters:
      service: hana
      service-plan: hdi-shared
```

### 7. Approuterを追加
※Managed Approuterを使用してSAP Build Workzoneからアクセスする場合は不要

```
cds add approuter --for production
```

Approuter経由でログイン後、リダイレクトURLが許可されていない旨のエラーが出た場合はxs-security.jsonに以下の設定を追加してデプロイしてください。


```json
{
  "scopes": [],
  "attributes": [],
  "role-templates": [],
  "oauth2-configuration": {
      "redirect-uris": [
          "https://*.hana.ondemand.com/login/callback"
      ]
  }

}
```
### 8. package-lock.jsonを生成

```
npm update --package-lock-only
```

### 9. ビルド

```
mbt build -t gen --mtar mta.tar
```

### 10. デプロイ

```
cf deploy gen/mta.tar
```

デプロイ後、ApprouterのURLにアクセスすると"Not found"と言われますが、これはapp/xs-app.jsonでWelcomeFileが存在しないファイル(index.html)を指しているためです。

```
  "welcomeFile": "app/index.html",
```

URLの末尾を`/odata/v4/CatalogService/Books`に変えればデータが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/c716b7ea-62b8-3e62-c750-64bf7ad115b0.png)

## ソースコード
上記の手順で作成したプロジェクトを以下のGitリポジトリに格納しています。
https://github.com/miyasuta/java-mta/tree/main