Stub Runner Core

存根运行核心用于运行服务协作方的存根。将存根视为服务的契约,可使存根运行器作为消费者驱动契约的实现。spring-doc.cadn.net.cn

Stub Runner 允许您自动下载所提供依赖项的存根(或从类路径中选择),为它们启动 WireMock 服务器,并为其提供适当的存根定义。对于消息传递,会定义特殊的存根路由。spring-doc.cadn.net.cn

获取存根

您可以从以下选项中选择获取存根的方式:spring-doc.cadn.net.cn

  • 基于Aether的解决方案,可从Artifactory或Nexus下载包含存根(stubs)的JAR文件spring-doc.cadn.net.cn

  • 类路径扫描解决方案,通过模式搜索类路径以检索存根spring-doc.cadn.net.cn

  • 编写您自己的 org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder 实现以实现完全自定义spring-doc.cadn.net.cn

后一个示例在自定义存根运行器部分中进行描述。spring-doc.cadn.net.cn

下载存根

您可以使用 stubsMode 开关来控制存根的下载。它会从 StubRunnerProperties.StubsMode 枚举中选取值。您可使用以下选项:spring-doc.cadn.net.cn

以下示例从本地位置选择存根:spring-doc.cadn.net.cn

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

类路径扫描

如果您将 stubsMode 属性设置为 StubRunnerProperties.StubsMode.CLASSPATH(或不进行任何设置,因为 CLASSPATH 是默认值),则会扫描类路径。请参见以下示例:spring-doc.cadn.net.cn

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

您可以将依赖项添加到您的类路径中,如下所示:spring-doc.cadn.net.cn

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,以下位置将被扫描:spring-doc.cadn.net.cn

对于 com.example.thing1:thing2,将扫描以下位置:spring-doc.cadn.net.cn

在打包生产者存根时,您必须显式提供组 ID 和构件 ID。

为了实现正确的存根打包,生产者将按如下方式设置契约:spring-doc.cadn.net.cn

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

通过使用 Maven assembly 插件 或者 Gradle Jar 任务,您必须在您的存根 JAR 中创建以下结构:spring-doc.cadn.net.cn

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

通过保持这种结构,类路径将被扫描,您即可无需下载构件(artifacts)便能利用消息传递或 HTTP 模拟(stubs)功能。spring-doc.cadn.net.cn

配置 HTTP 服务器存根

Stub Runner有一个抽象底层HTTP服务器(例如,WireMock是其中一种实现)的HttpServerStub的概念。有时,您需要执行一些额外的调整(这是给定实现的具体调整),Stub Runner通过注释和JUnit规则中可用的httpServerStubConfigurer属性以及系统属性来提供该属性,您可以在其中提供org.springframework.cloud.contract.stubrunner.HttpServerStubConfigurer接口的实现,这些实现可以修改给定HTTP服务器存档的配置文件。spring-doc.cadn.net.cn

Spring Cloud Contract Stub Runner 提供了一个可以扩展用于 WireMock 的实现: org.springframework.cloud.contract.stubrunner.provider.wiremock.WireMockHttpServerStubConfigurer。 在 configure 方法中,您可以为给定存档提供自己的自定义配置。用例可能是针对给定的 artifact ID 启动 WireMock,在 HTTPS 端口上。下面的示例展示了如何做到这一点:spring-doc.cadn.net.cn

示例 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 注解重用它,如下所示:spring-doc.cadn.net.cn

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

每当找到一个HTTPS端口,它都会优先于HTTP端口。spring-doc.cadn.net.cn

正在存根中运行

此部分介绍了如何运行存根。它包含以下主题:spring-doc.cadn.net.cn

HTTP Stubs

存档是在 JSON 文档中定义的,其语法在 WireMock 文档 中进行了定义。spring-doc.cadn.net.cn

下面的例子用 JSON 定义了一个存档。spring-doc.cadn.net.cn

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

查看已注册的映射

每个存根协作对象都在__/admin/端点下公开定义的映射列表。spring-doc.cadn.net.cn

你也可以使用mappingsOutputFolder属性,将其映射输出到文件。对于注解方法,它会类似以下示例:spring-doc.cadn.net.cn

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

对于 JUnit 方法,其外观类似于以下示例:spring-doc.cadn.net.cn

@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 文件夹,你会看到以下结构;spring-doc.cadn.net.cn

.
├── fraudDetectionServer_13705
└── loanIssuance_12255

这意味着注册了两个存根。在端口13705注册了fraudDetectionServer,在端口12255注册了loanIssuance。如果我们查看其中一个文件,就会看到(对于WireMock),给定服务器提供的映射:spring-doc.cadn.net.cn

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

Messaging Stubs

根据提供的 Stub Runner 依赖项和 DSL,消息路由将自动设置。spring-doc.cadn.net.cn