スタブランナーコア

スタブランナーコアは、サービスコラボレータのスタブを実行します。スタブをサービスの契約として扱うと、コンシューマー主導の契約 (英語) の実装として stub-runner を使用できるようになります。

Stub Runner を使用すると、提供された依存関係のスタブを自動的にダウンロードし (またはクラスパスから選択し)、それらの WireMock サーバーを起動し、適切なスタブ定義をそれらに供給できます。メッセージングの場合、特別なスタブルートが定義されます。

スタブの取得

スタブを取得するには、次のオプションから選択できます。

  • Artifactory または Nexus からスタブ付きの JAR をダウンロードする Aether ベースのソリューション

  • パターンでクラスパスを検索してスタブを取得するクラスパススキャンソリューション

  • 完全なカスタマイズのための独自の org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder 実装の作成

後者の例については、カスタムスタブランナーセクションで説明します。

スタブのダウンロード

stubsMode スイッチを使用してスタブのダウンロードを制御できます。StubRunnerProperties.StubsMode 列挙から値を選択します。次のオプションを使用できます。

  • StubRunnerProperties.StubsMode.CLASSPATH (デフォルト値): クラスパスからスタブを選択します

  • StubRunnerProperties.StubsMode.LOCAL: ローカルストレージからスタブを取得します (たとえば、.m2)

  • StubRunnerProperties.StubsMode.REMOTE: リモート の場所からスタブを選択します

次の例では、ローカルの場所からスタブを選択します。

@AutoConfigureStubRunner(repositoryRoot="https://foo.bar", ids = "com.example:beer-api-producer:+:stubs:8095", stubsMode = StubRunnerProperties.StubsMode.LOCAL)

クラスパスのスキャン

stubsMode プロパティを StubRunnerProperties.StubsMode.CLASSPATH に設定した場合 (または、CLASSPATH がデフォルト値であるため何も設定しなかった場合)、クラスパスがスキャンされます。次の例を考えてみましょう。

@AutoConfigureStubRunner(ids = {
    "com.example:beer-api-producer:+:stubs:8095",
    "com.example.foo:bar:1.0.0:superstubs:8096"
})

次のように、依存関係をクラスパスに追加できます。

Maven
<dependency>
    <groupId>com.example</groupId>
    <artifactId>beer-api-producer-restdocs</artifactId>
    <classifier>stubs</classifier>
    <version>0.0.1-SNAPSHOT</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>com.example.thing1</groupId>
    <artifactId>thing2</artifactId>
    <classifier>superstubs</classifier>
    <version>1.0.0</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>
Gradle
testCompile("com.example:beer-api-producer-restdocs:0.0.1-SNAPSHOT:stubs") {
    transitive = false
}
testCompile("com.example.thing1:thing2:1.0.0:superstubs") {
    transitive = false
}

次に、クラスパス上の指定された場所がスキャンされます。com.example:beer-api-producer-restdocs の場合、次の場所がスキャンされます。

  • /META-INF/com.example/beer-api-producer-restdocs/ */ .*

  • /contracts/com.example/beer-api-producer-restdocs/ */ .*

  • /mappings/com.example/beer-api-producer-restdocs/ */ .*

com.example.thing1:thing2 の場合、次の場所がスキャンされます。

  • /META-INF/com.example.thing1/thing2/ */ .*

  • /contracts/com.example.thing1/thing2/ */ .*

  • /mappings/com.example.thing1/thing2/ */ .*

プロデューサースタブをパッケージ化するときは、グループ ID とアーティファクト ID を明示的に指定する必要があります。

適切なスタブパッケージ化を実現するには、プロデューサーは次のように契約を設定します。

└── src
    └── test
        └── resources
            └── contracts
                └── com.example
                    └── beer-api-producer-restdocs
                        └── nested
                            └── contract3.groovy

Maven assembly プラグイン [GitHub] (英語) タスクまたは Gradle Jar [GitHub] (英語) タスクを使用して、スタブ jar に次の構造を作成する必要があります。

└── META-INF
    └── com.example
        └── beer-api-producer-restdocs
            └── 2.0.0
                ├── contracts
                │   └── nested
                │       └── contract2.groovy
                └── mappings
                    └── mapping.json

この構造を維持することで、クラスパスがスキャンされ、アーティファクトをダウンロードしなくてもメッセージングまたは HTTP スタブから利益を得ることができます。

HTTP サーバースタブの構成

スタブランナーには、HTTP サーバーの基礎となる具体的な実装を抽象化する HttpServerStub の概念があります (たとえば、WireMock は実装の 1 つです)。場合によっては、スタブサーバーの追加のチューニング (特定の実装に具体的なもの) を実行する必要があります。これを行うために、Stub Runner は、アノテーションと JUnit ルールで使用可能であり、システムプロパティを通じてアクセスできる httpServerStubConfigurer プロパティを提供します。これにより、org.springframework.cloud.contract.stubrunner.HttpServerStubConfigurer インターフェースの実装を提供できます。実装では、特定の HTTP サーバースタブの構成ファイルを変更できます。

Spring Cloud Contract スタブランナーには、WireMock 用に拡張できる実装 ( org.springframework.cloud.contract.stubrunner.provider.wiremock.WireMockHttpServerStubConfigurer) が付属しています。configure メソッドでは、特定のスタブに独自のカスタム構成を提供できます。使用例としては、HTTPS ポート上で、指定されたアーティファクト ID に対して WireMock を開始することが考えられます。次の例は、その方法を示しています。

例 1: WireMockHttpServerStubConfigurer の実装
@CompileStatic
static class HttpsForFraudDetection extends WireMockHttpServerStubConfigurer {

	private static final Log log = LogFactory.getLog(HttpsForFraudDetection)

	@Override
	WireMockConfiguration configure(WireMockConfiguration httpStubConfiguration, HttpServerStubConfiguration httpServerStubConfiguration) {
		if (httpServerStubConfiguration.stubConfiguration.artifactId == "fraudDetectionServer") {
			int httpsPort = TestSocketUtils.findAvailableTcpPort()
			log.info("Will set HTTPs port [" + httpsPort + "] for fraud detection server")
			return httpStubConfiguration
					.httpsPort(httpsPort)
		}
		return httpStubConfiguration
	}
}

次に、次のように @AutoConfigureStubRunner アノテーションを付けて再利用できます。

@AutoConfigureStubRunner(mappingsOutputFolder = "target/outputmappings/",
		httpServerStubConfigurer = HttpsForFraudDetection)

HTTPS ポートが見つかると、HTTP ポートよりも優先されます。

実行中のスタブ

このセクションでは、スタブを実行する方法について説明します。以下のトピックが含まれています。

HTTP スタブ

スタブは JSON ドキュメントで定義され、その構文は WireMock ドキュメント (英語) で定義されます。

次の例では、JSON でスタブを定義します。

{
    "request": {
        "method": "GET",
        "url": "/ping"
    },
    "response": {
        "status": 200,
        "body": "pong",
        "headers": {
            "Content-Type": "text/plain"
        }
    }
}

登録されたマッピングの表示

スタブ化されたすべてのコラボレータは、__/admin/ エンドポイントで定義されたマッピングのリストを公開します。

mappingsOutputFolder プロパティを使用して、マッピングをファイルにダンプすることもできます。アノテーションベースのアプローチの場合、次の例のようになります。

@AutoConfigureStubRunner(ids="a.b.c:loanIssuance,a.b.c:fraudDetectionServer",
mappingsOutputFolder = "target/outputmappings/")

JUnit アプローチの場合、次の例のようになります。

@ClassRule @Shared StubRunnerRule rule = new StubRunnerRule()
			.repoRoot("https://some_url")
			.downloadStub("a.b.c", "loanIssuance")
			.downloadStub("a.b.c:fraudDetectionServer")
			.withMappingsOutputFolder("target/outputmappings")

次に、target/outputmappings フォルダーをチェックアウトすると、次の構造が表示されます。

.
├── fraudDetectionServer_13705
└── loanIssuance_12255

つまり、スタブが 2 つ登録されていたことになります。fraudDetectionServer はポート 13705 に登録され、loanIssuance はポート 12255 に登録されました。ファイルの 1 つを見ると、指定されたサーバーで利用可能なマッピング (WireMock の場合) が表示されます。

[{
  "id" : "f9152eb9-bf77-4c38-8289-90be7d10d0d7",
  "request" : {
    "url" : "/name",
    "method" : "GET"
  },
  "response" : {
    "status" : 200,
    "body" : "fraudDetectionServer"
  },
  "uuid" : "f9152eb9-bf77-4c38-8289-90be7d10d0d7"
},
...
]

メッセージングスタブ

提供された Stub Runner の依存関係と DSL に応じて、メッセージングルートが自動的にセットアップされます。