スタブランナーコア
スタブランナーコアは、サービスコラボレータのスタブを実行します。スタブをサービスの契約として扱うと、コンシューマー主導の契約 (英語) の実装として 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"
})
次のように、依存関係をクラスパスに追加できます。
<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>
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 を開始することが考えられます。次の例は、その方法を示しています。
@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"
},
...
]