サブアカウント版とインスタンス版のDestinationの関係

## はじめに

この記事は [SAP Advent Calendar 2023](https://adventar.org/calendars/8870) の12月16日分の記事として執筆しています。

### 概要
SAP BTPの接続先を定義するDestinationサービスについて、疑問に思ったことがあったので調査しました。
ブログ自体初投稿なのでお手柔らかにお願いします。

### 対象読者様
- Destinationサービス使用したアプリケーション開発の経験がある方
- 最低限のJava知識がある方


### ことの発端
皆さんご存知の通り、Destinationにはサブアカウント画面から操作するDestinationとインスタンス画面から操作するDestinationの２つがあります。
通常、DestinationをCFのアプリから使用する際は、Destinationインスタンスとアプリをサービスバインディングさせて使用します。
ここで疑問に思ったのが、本来CFアプリケーションとは何も紐づきがないはずのサブアカウントDestinationの情報をなぜか取得できます。
この疑問を解消すべく検証をしてみました。

**全体イメージ**
![イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633975/0ff7d684-0dfb-ff70-4c66-065a970c8523.png)

## 手っ取り早く結論
Destinationインスタンスの役割は
- 接続情報の管理
- サブアカウントのDestination情報を自動取得している可能性が高い

です。(内部構造がわからないので断定はできません)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633975/b3aeb4be-46b3-11c6-b28b-e927212a6619.png)


## 検証

### 前提条件
- 言語はJava
- SAP Cloud SDKを使用
- Destinationの接続先は[SAP SandBox環境](https://api.sap.com/api/API_BUSINESS_PARTNER/overview)のBusiness Partner APIを使用
- プログラムは取得したAPIを文字列にして返すだけ
- どのDesitnationかわかりやすいようAdditional Properipiesの値を合わせて返却
- [ソースコード](https://github.com/ishikawajun/Destination) 
```java:DestinationService.java
@Service
public class DestinationService {
	
	public String getBusinessPartner() {
		try {
			final HttpDestination destination = DestinationAccessor.getDestination("DestinationName").asHttp();
            // どのDesitnationかわかりやすいようAdditional Properipiesの値を取得
            final String destinationPropety = destination.get("Test.Propety").toString();
			final BusinessPartnerService service = new DefaultBusinessPartnerService();
			final List<BusinessPartner> result = service.getAllBusinessPartner().top(5).executeRequest(destination);
			return "destinationPropety:" + destinationPropety + " " + result;	
		} catch (Exception e) {
			return e.toString();
		}

	}

}	
```

### 検証① 通常パターン
Destinationインスタンスとアプリケーションをサービスバインディングさせて実行
![検証①イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633975/86727950-fca3-9c6f-9bf9-970f925ed4aa.png)

#### 結果
当たり前だけど使用できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633975/f41ff685-66e5-edcf-89c3-d73e4a7df0b5.png)

### 検証②　失敗パターン
Destinationインスタンスとアプリケーションをサービスバインディングさせないで実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633975/a80a8679-4f17-297a-cffa-62ff77b15942.png)

#### 結果
これも当たり前だけど使用できない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633975/af4bff16-08cf-ec3b-6226-fb2a8d49981e.png)

### 検証③ サブアカウントのDestination取得
Destinationインスタンスとアプリケーションをサービスバインディングさせたうえで、サブアカウントDestinationにも接続情報を設定し実行。(インスタンスDestinationには接続情報を設定しない。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633975/f418586a-50cc-e24d-fd55-bfd6a23cc730.png)

#### 結果
取得できる！！
またインスタンスのDestinationには何も情報を設定していないので、**インスタンスDestinationの設定有無に関わらず、サービスバインディングさえすればサブアカウントDestinationの情報は取得可能！！**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633975/a38a1c0e-d8a1-6bd3-7113-4a2e86b71bce.png)

### 検証④　バインディングをせずサブアカウントDestinationを取得
Destinationインスタンス自体は存在するが、アプリケーションとサービスバインディングをしない状態でサブアカウントDestinationを取得するよう実行。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633975/9953b016-101f-fcac-3cbd-5a35c3129df0.png)

#### 結果
取得できない！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633975/e2707cf9-9009-e12a-967c-10c12d970153.png)


検証①～④の結果からすると
- インスタンスDestinationとアプリケーションがサービスバインディングされていればサブアカウントDestinationの設定は不要(検証①、②)
- サブアカウントDestinationを使用する場合は必ずインスタンスDestinationとアプリケーションのサービスバインディングが必要(検証④)
- ただしインスタンスDestinationには何も設定しなくても接続することが可能(検証③)

になり、Destinationインスタンスは接続先情報の管理とは別に、**サブアカウントDestinationの情報を取得する役割**があるのではないかと思います。(内部構造がわからないので、断定はできませんが)

## まとめ
内容としてはHelpPortalを探せば見つかりそうな気もしますが、実際に手を動かして検証することで、より深い理解ができました。
やはり手を動かすは正義です笑

## 番外編　サブアカウントとインスタンスで同名Destinationを作成した場合は？
サブアカウントDestinationをインスタンスDestinationからそれぞれ接続情報を取得できることがわかりましたが、Destination名が同名の場合はどうなるでしょう？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633975/cd4754ba-a949-91ee-7894-1d59801d1d59.png)

#### 結果
インスタンスDestinationが優先されます。使用する際は注意しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633975/4277fc49-ec88-310d-1630-82620dbfc007.png)

##### 参考
```java:DestinationService.java
@Service
public class DestinationService {
	
	public String getBusinessPartner() {
		try {
			final HttpDestination destination = DestinationAccessor.getDestination("Same").asHttp();
            final String destinationPropety = destination.get("Test.Propety").toString();
			final BusinessPartnerService service = new DefaultBusinessPartnerService();
			final List<BusinessPartner> result = service.getAllBusinessPartner().top(5).executeRequest(destination);
			return "destinationPropety:" + destinationPropety + " " + result;	
		} catch (Exception e) {
			return e.toString();
		}

	}

}	
```