spring-cloud-contract 是否可以为合同和合同测试规范制定一个 OpenApi3 定义?
Is it possible to have one OpenApi3 definition for contract and for contract test specification which will be parsable by spring-cloud-contract?
我们的想法是将一个文件用于合同定义和合同测试规范。
我找到了插件 'guru.springframework:spring-cloud-contract-oa3:2.1.2.0',它应该可以满足我的需求,但对我来说却失败了。
我的配置基于此 repo 中的示例
https://github.com/springframeworkguru/sccoa3-fraud-example
这是执行后的错误信息
gradle build clean
Error Processing yaml file. Skipping Contract Generation
java.lang.IllegalStateException: Exception occurred while processing the file [.../build/stubs/META-INF/com.bla.bla/api-mlpe/0.0.1-SNAPSHOT/contracts/v1/0/openapi.yml]
...
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "openapi" (class org.springframework.cloud.contract.verifier.converter.YamlContract), not marked as ignorable (10 known properties: "response", "ignored", "label", "outputMessage", "input", "name", "description", "request", "inProgress", "priority"])
at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: org.springframework.cloud.contract.verifier.converter.YamlContract["openapi"])
这是我的 build.gradle 配置
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.springframework.cloud:spring-cloud-contract-gradle-plugin:2.2.4.RELEASE'
}
}
plugins {
id 'org.springframework.boot' version '2.3.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
apply plugin: 'spring-cloud-contract'
group = 'com.bla.bla'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "Hoxton.SR8")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework:spring-web:5.2.9.RELEASE'
implementation 'guru.springframework:spring-cloud-contract-oa3:2.1.2.0'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-verifier'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
contracts {
testFramework = org.springframework.cloud.contract.verifier.config.TestFramework.JUNIT5
}
test {
useJUnitPlatform()
testLogging {
exceptionFormat = 'full'
}
}
这里是 openapi.yml(基于前面提到的回购协议,放在 test/resources/contracts 下)
openapi: 3.0.3
info:
description: Spring Cloud Contract Verifier Http Server OA3 Sample
version: "1.0.0"
title: Fraud Service API
paths:
/v1/consumers/global-consumers:
put:
summary: Perform Fraud Check
x-contracts:
- contractId: 1
name: Should Mark Client as Fraud
priority: 1
- contractId: 2
name: Should Not Mark Client as Fraud
requestBody:
content:
application/json:
schema:
type: object
properties:
"client.id":
type: integer
loanAmount:
type: integer
#START REQUEST - part with SPEC definitions
x-contracts:
- contractId: 1
body:
"client.id": 1234567890
loanAmount: 99999
matchers:
body:
- path: $.['client.id']
type: by_regex
value: "[0-9]{10}"
- contractId: 2
body:
"client.id": 1234567890
loanAmount: 123.123
matchers:
body:
- path: $.['client.id']
type: by_regex
value: "[0-9]{10}"
#END REQUEST - part with SPEC definitions
responses:
'200':
description: created ok
content:
application/json:
schema:
type: object
properties:
fraudCheckStatus:
type: string
"rejection.reason":
type: string
#START RESPONSE - part with SPEC definitions
x-contracts:
- contractId: 1
body:
fraudCheckStatus: "FRAUD"
"rejection.reason": "Amount too high"
headers:
Content-Type: application/json;charset=UTF-8
- contractId: 2
body:
fraudCheckStatus: "OK"
"rejection.reason": null
headers:
Content-Type: application/json;charset=UTF-8
matchers:
body:
- path: $.['rejection.reason']
type: by_command
value: assertThatRejectionReasonIsNull($it)
#END RESPONSE - part with SPEC definitions
除了失败之外,我不确定我的配置是否适合实现我的目标:-)
我的目标是拥有一个描述合同的文件(在 OpenApi3 标准中),包括合同测试规范(在同一个文件中,不应破坏 OpenAPI3 规范标准)并基于我要生成的文件:
- api 模特 类
- java假装类
- 节点存根模块
- wiremock 存根
- api 合同测试(jUnit5 或 Spock)
是否可以按照我指定的方式全部拥有?如果是 - 如何实现?
提到的插件在提供的配置中对我不起作用。
您需要将 guru.springframework:spring-cloud-contract-oa3:2.1.2.0
依赖添加到插件的类路径而不是项目的类路径。
不是这样的:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.springframework.cloud:spring-cloud-contract-gradle-plugin:2.2.4.RELEASE'
}
}
plugins {
id 'org.springframework.boot' version '2.3.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
像这样:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.springframework.cloud:spring-cloud-contract-gradle-plugin:2.2.4.RELEASE'
classpath 'guru.springframework:spring-cloud-contract-oa3:2.1.2.0'
}
}
plugins {
id 'org.springframework.boot' version '2.3.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
我们也在文档中描述了这一点(在另一个例子中)https://docs.spring.io/spring-cloud-contract/docs/2.2.4.RELEASE/reference/html/advanced.html#customization-plugin-dep
哦,真是个蹩脚的错误。谢谢@marcin-grzejszczak
应用更改后,它看起来更好。解析 yaml 规范有效。
现在我在 generateClientStubs
中遇到问题
在 运行 之后
gradle clean build -x test --stacktrace
我正在
Execution failed for task ':generateClientStubs'.
13:43:33.759 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] > Class org.springframework.cloud.contract.verifier.converter.YamlContract does not implement the requested interface groovy.lang.GroovyObject
….
Caused by: java.lang.IncompatibleClassChangeError: Class org.springframework.cloud.contract.verifier.converter.YamlContract does not implement the requested interface groovy.lang.GroovyObject
at org.springframework.cloud.contract.verifier.converter.OpenApiContractConverter$_convertFrom_closure2$_closure5$_closure6.doCall(OpenApiContractConverter.groovy:84)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
我发现前段时间报告的问题看起来很相似
[https://github.com/spring-cloud/spring-cloud-contract/issues/1289]
现在我的构建 gradle 中定义的版本是两天前通过 spring initializr 生成的版本,所以我假设它们应该是兼容的。
这个问题有没有可能是因为添加了‘guru.springframework:spring-cloud-contract-oa3’插件?
乍一看,它很像提到的类似报告问题。
我们的想法是将一个文件用于合同定义和合同测试规范。
我找到了插件 'guru.springframework:spring-cloud-contract-oa3:2.1.2.0',它应该可以满足我的需求,但对我来说却失败了。 我的配置基于此 repo 中的示例 https://github.com/springframeworkguru/sccoa3-fraud-example
这是执行后的错误信息
gradle build clean
Error Processing yaml file. Skipping Contract Generation
java.lang.IllegalStateException: Exception occurred while processing the file [.../build/stubs/META-INF/com.bla.bla/api-mlpe/0.0.1-SNAPSHOT/contracts/v1/0/openapi.yml]
...
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "openapi" (class org.springframework.cloud.contract.verifier.converter.YamlContract), not marked as ignorable (10 known properties: "response", "ignored", "label", "outputMessage", "input", "name", "description", "request", "inProgress", "priority"])
at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: org.springframework.cloud.contract.verifier.converter.YamlContract["openapi"])
这是我的 build.gradle 配置
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.springframework.cloud:spring-cloud-contract-gradle-plugin:2.2.4.RELEASE'
}
}
plugins {
id 'org.springframework.boot' version '2.3.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
apply plugin: 'spring-cloud-contract'
group = 'com.bla.bla'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "Hoxton.SR8")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework:spring-web:5.2.9.RELEASE'
implementation 'guru.springframework:spring-cloud-contract-oa3:2.1.2.0'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-verifier'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
contracts {
testFramework = org.springframework.cloud.contract.verifier.config.TestFramework.JUNIT5
}
test {
useJUnitPlatform()
testLogging {
exceptionFormat = 'full'
}
}
这里是 openapi.yml(基于前面提到的回购协议,放在 test/resources/contracts 下)
openapi: 3.0.3
info:
description: Spring Cloud Contract Verifier Http Server OA3 Sample
version: "1.0.0"
title: Fraud Service API
paths:
/v1/consumers/global-consumers:
put:
summary: Perform Fraud Check
x-contracts:
- contractId: 1
name: Should Mark Client as Fraud
priority: 1
- contractId: 2
name: Should Not Mark Client as Fraud
requestBody:
content:
application/json:
schema:
type: object
properties:
"client.id":
type: integer
loanAmount:
type: integer
#START REQUEST - part with SPEC definitions
x-contracts:
- contractId: 1
body:
"client.id": 1234567890
loanAmount: 99999
matchers:
body:
- path: $.['client.id']
type: by_regex
value: "[0-9]{10}"
- contractId: 2
body:
"client.id": 1234567890
loanAmount: 123.123
matchers:
body:
- path: $.['client.id']
type: by_regex
value: "[0-9]{10}"
#END REQUEST - part with SPEC definitions
responses:
'200':
description: created ok
content:
application/json:
schema:
type: object
properties:
fraudCheckStatus:
type: string
"rejection.reason":
type: string
#START RESPONSE - part with SPEC definitions
x-contracts:
- contractId: 1
body:
fraudCheckStatus: "FRAUD"
"rejection.reason": "Amount too high"
headers:
Content-Type: application/json;charset=UTF-8
- contractId: 2
body:
fraudCheckStatus: "OK"
"rejection.reason": null
headers:
Content-Type: application/json;charset=UTF-8
matchers:
body:
- path: $.['rejection.reason']
type: by_command
value: assertThatRejectionReasonIsNull($it)
#END RESPONSE - part with SPEC definitions
除了失败之外,我不确定我的配置是否适合实现我的目标:-) 我的目标是拥有一个描述合同的文件(在 OpenApi3 标准中),包括合同测试规范(在同一个文件中,不应破坏 OpenAPI3 规范标准)并基于我要生成的文件:
- api 模特 类
- java假装类
- 节点存根模块
- wiremock 存根
- api 合同测试(jUnit5 或 Spock)
是否可以按照我指定的方式全部拥有?如果是 - 如何实现? 提到的插件在提供的配置中对我不起作用。
您需要将 guru.springframework:spring-cloud-contract-oa3:2.1.2.0
依赖添加到插件的类路径而不是项目的类路径。
不是这样的:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.springframework.cloud:spring-cloud-contract-gradle-plugin:2.2.4.RELEASE'
}
}
plugins {
id 'org.springframework.boot' version '2.3.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
像这样:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.springframework.cloud:spring-cloud-contract-gradle-plugin:2.2.4.RELEASE'
classpath 'guru.springframework:spring-cloud-contract-oa3:2.1.2.0'
}
}
plugins {
id 'org.springframework.boot' version '2.3.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
我们也在文档中描述了这一点(在另一个例子中)https://docs.spring.io/spring-cloud-contract/docs/2.2.4.RELEASE/reference/html/advanced.html#customization-plugin-dep
哦,真是个蹩脚的错误。谢谢@marcin-grzejszczak 应用更改后,它看起来更好。解析 yaml 规范有效。
现在我在 generateClientStubs
中遇到问题在 运行 之后
gradle clean build -x test --stacktrace
我正在
Execution failed for task ':generateClientStubs'.
13:43:33.759 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] > Class org.springframework.cloud.contract.verifier.converter.YamlContract does not implement the requested interface groovy.lang.GroovyObject
….
Caused by: java.lang.IncompatibleClassChangeError: Class org.springframework.cloud.contract.verifier.converter.YamlContract does not implement the requested interface groovy.lang.GroovyObject
at org.springframework.cloud.contract.verifier.converter.OpenApiContractConverter$_convertFrom_closure2$_closure5$_closure6.doCall(OpenApiContractConverter.groovy:84)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
我发现前段时间报告的问题看起来很相似 [https://github.com/spring-cloud/spring-cloud-contract/issues/1289] 现在我的构建 gradle 中定义的版本是两天前通过 spring initializr 生成的版本,所以我假设它们应该是兼容的。 这个问题有没有可能是因为添加了‘guru.springframework:spring-cloud-contract-oa3’插件? 乍一看,它很像提到的类似报告问题。