SoapUIでSOAPとREST兼用のモックサーバを立てる

## はじめに
この記事は [NRI OpenStandia Advent Calendar 2023](https://qiita.com/advent-calendar/2023/nri-openstandia) の9日目の記事です。

新規システム開発でAPIを構築する場合、現在はREST形式のAPIを作るのが一般的かと思います。
一方で、既存システムにはSOAP形式のAPIがあり、既存システムとの連携でSOAPの呼び出しが必要、といったケースがあります。  

このような場合、テスト工程ではSOAPもRESTもモックサーバが欲しくなるわけですが、SOAPとRESTそれぞれで異なるツールを使うのも面倒なので一つのツールでまとめて対応できないか・・・そんな時、SOAPのモックサーバとして有名なSoapUIをRESTも兼用で使ってしまおう、というお話です。

## SoapUIを使うメリット
[SoapUI Open Source](https://www.soapui.org/tools/soapui/)とは、SmartBear社が展開するオープンソースのAPI Testing Toolです。
SoapUIを使うメリットは以下の点にあると考えています。

 * SOAPとREST両方のモックサーバを立てることができる
 * GUIツールを使ってエンドポイントの設定やモックデータの作成を行うことができる
 * 作成したモックサーバの設定をWindows/Linux両方の環境で利用することができる 

これらの実現方法について、簡単なサンプルを使った利用手順に沿って見ていきましょう。
    
## 1. SoapUIのインストールと起動
インストーラをダウンロードして、ダイアログに従ってインストールすればOKです。
以降、開発端末としてWindowsを使う想定で説明します。

## 2. SOAPモックサーバの作成
### 2-1. SOAP Projectの作成
SOAP用のプロジェクトは、WSDLをimportすることで作成が可能です。
ここでは、Apache Axis2のサンプルアプリケーションに含まれるWSDLを例としてプロジェクトを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417946/44c420f6-9442-7837-9ad4-6e9d938da4c0.png)

WSDLをもとにプロジェクトを作成すると、WSDLで定義されているインタフェースに対するクライアントが生成されます。
このWSDLでは「VersionSoap11Binding」と「VersionSoap12Binding」という2つのインタフェースが公開されていることが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417946/42a95287-2651-663f-06cb-2fcb0c32358e.png)

### 2-2. SOAP Mock Serviceの作成
モックを作成したいインタフェース名を右クリックし、```Generate SOAP Mock Service``` を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417946/6269f095-3749-e7fa-c585-8ade09758283.png)

パスやポート番号などを指定するダイアログが表示されるので、任意の値を指定します。
パスは実際に接続するSOAPのエンドポイントに合わせたものにするのが良いでしょう。
ポート番号は、他にもモックサーバを立てる場合は重複しないようにルールを決めておくとよいでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417946/a220ccca-a73c-711a-e9bb-254b1026db17.png)

あとは名前を決めたら作成完了です。

### 2-3. SOAPモックデータの設定
作成したMock Serviceは、以下の構成になっています。
 * MockService 
パスやポート番号など、モックサーバの接続情報を管理
   * └MockOperation
　WSDLのオペレーションとの関連付けと、モックレスポンスの振り分けを管理
     * └MockResponse
　レスポンスとして返却するモックデータを管理

 MockServiceやMockOperationは作成する過程で設定済みなので、モックサーバが返却するデータを定義しているMockResponseを編集します。
 MockResponseにはWSDLで定義されたSOAP Envelopeが記述されており、初期状態では値がすべて```?```となっていますので、モックサーバとして返却したい値で更新していけばOKです。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417946/ca31eaaa-b7fb-bab3-7649-c68951238ae8.png)

### 2-4. SOAPモックサーバの起動
値の設定が完了したら、あとはMockServiceを起動すればOKです。
プロジェクトからMockServiceを開き、再生アイコンをクリックすれば起動できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417946/f8294afe-8052-6d4b-408a-5a66301cd518.png)

プロジェクトにあるクライアント機能を使ってSOAPリクエストを送信すると、設定したモックデータが返却されることを確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417946/f86babf7-5d20-d824-b90e-054040045115.png)

## 3. REST モックサーバの作成
### 3-1. REST Projectの作成
SOAPプロジェクトと同様にWADLやSwagger定義をインポートして作成することも可能ですが、ここでは空のプロジェクトを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417946/72ecfc4d-f9dd-2793-054a-1fae8b6b2fc7.png)

### 3-2. REST Mock Serviceの作成
プロジェクトを作成した後の流れはSOAPと同じです。
モックを生成したいインタフェース名を右クリックし、```Generate REST Mock Service```を選択、モックサービス名を入力すれば作成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417946/5bca0e8a-ae62-7c2c-e04e-12d036958ead.png)

作成後、ポート番号などは重複しないよう適宜設定を変更しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417946/426d8523-e108-6b7c-9bd1-d0ed7942e3cb.png)

### 3-3. RESTモックデータの設定
モックサーバが返却するデータを設定します。
初期状態では```Response 1```というMockResponseが生成されているので、これを開きモックデータを設定します。
 * Content-Typeとして application/jsonを選択
 * レスポンスとなるJSONデータを定義

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417946/0eaa70ce-fd74-4166-3463-c23305924f54.png)

最低限はこれらを設定すれば良いでしょう。HTTPレスポンスヘッダを追加することも可能です。

### 3-4. RESTモックサーバの起動
こちらもSOAPと同様に、プロジェクトからMockServiceを開き再生アイコンをクリックすれば起動できます。
クライアントからリクエストを送信すると、設定したモックデータが返ってくることが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417946/f093081e-29f3-c78b-c157-0554fe4a259e.png)

## 4. 作成したモックサーバをLinux上で起動する
単体開発では開発者がWindowsのローカルマシンで開発を行い、連結テスト以降はテスト用に構築されたLinux環境を利用する・・・といった流れは、（特に大規模開発では）よくあるケースだと思います。
単体開発で利用するためにWindows上で作成したモックサーバの設定やモックデータを、そのままLinuxの連結テスト環境でも利用することができます。

### 4-1. 作成したプロジェクトの保存
作成したプロジェクトは、xml形式のSoapUIプロジェクトファイルとして保存することができます。
プロジェクトを選択して```Ctrl+S```でプロジェクトの保存ができますので、ファイル名を指定して保存しておきます。

### 4-2. Linux用SoapUIの取得とインストール
Linux用のモジュールとして.tar.gz形式のファイルが公開されていますので、これをダウンロードしてLinux環境の適当な場所に展開して配置します。
保存したSoapUIプロジェクトのxmlファイルも同一サーバ上に配置しておきましょう。

### 4-3. Linux上でモックサーバを起動
モックサーバを起動するには、```SoapUI-X.X.X/bin/mockservicerunner.sh```を実行します。
引数にSoapUIプロジェクトファイルを渡せばOKです。

```bash
~/SoapUI-5.5.0/bin # ./mockservicerunner.sh ~/soapui-project/Sample-REST-Project-soapui-project.xml
================================
=
= SOAPUI_HOME = /home/apl/SoapUI-5.5.0
=
================================
SoapUI 5.5.0 MockService Runner
Configuring log4j from [/home/apl/SoapUI-5.5.0/bin/soapui-log4j.xml]
22:08:53,164 INFO  [DefaultSoapUICore] Creating new settings at [/home/apl/soapui-settings.xml]
22:08:54,086 INFO  [PluginManager] 0 plugins loaded in 2 ms
22:08:54,086 INFO  [DefaultSoapUICore] All plugins loaded
22:08:54,673 INFO  [WsdlProject] Loaded project from [file:/home/apl/soapui-project/Sample-REST-Project-soapui-project.xml]
22:08:54,676 INFO  [SoapUIMockServiceRunner] Running all MockServices in project [Sample REST Project]
22:08:54,677 INFO  [SoapUIMockServiceRunner] Press any key to terminate
22:08:54,780 INFO  [JettyMockEngine] Started mockService [Account creation mock] on port [8080] at path [/]
22:08:54,780 INFO  [SoapUIMockServiceRunner] MockService started on port 8080 at path [/]
22:08:54,780 INFO  [SoapUIMockServiceRunner] Started 1 runner
Press any key to terminate...

```

このとき、```-p```オプションを使うことでプロジェクトファイルで定義されたポート番号とは異なる番号を利用することができます。
連結テスト環境で複数のモックサーバを起動する際にポートが重複してしまった・・・なんて場合にはこれを指定して重複を回避すると良いでしょう。

## SoapUIのその他の機能
今回は紹介できませんでしたが、SoapUIにはMockResponseにスクリプトを仕込むことができるので、Sleepを入れて疑似的に滞留させたり、リクエストパラメータの値に応じて返却する値を動的に切り替えたりすることができます。
これらの機能を作りこむことで、様々なケースをモックサーバでテストすることが可能となります。


## まとめ
新規開発でSOAPのAPIを作るケースはあまりないと思いますが、現役で活用している組織もあると思います。
個人的には、2010年前後にSOAが流行した際、本気でサービス志向を目指してAPI化を推進した企業ほど、SOAP APIが今でも使える形で残っているために活用している、ということなのかと考えています。
SOAPは今後RESTやgRPCに置き換わっていくと思われますが、今でもSOAPを扱う人にとって少しでも参考になれば幸いです。