前言:spring-cloud-starter-contract-verifier:2.1.1.RELEASE.
spring-cloud-contract-maven-plugin:2.2.1.RELEASE.
spring-cloud-starter-contract-stub-runner:2.1.1.RELEASE.
我的项目是maven项目,groovy写的contract.
这里不会涉及怎么搭建和使用。网上已经有很多这种例子。假设读者已经具有Spring cloud contract的知识,建议用最新的版本,以前有人说用旧版本会比较稳定,我看这个spring cloud contract旧的版本不稳定呀。如果你是在用的时候遇到问题,估计我下面的内容应该可以解决到你的问题。下面是我爬坑记。
对于Producer:
我自己是用groovy写的contract.写完contract.还有BaseClass,你会在pom文件里面写上贴上你的BaseTestClass
org.springframework.cloud
spring-cloud-contract-maven-plugin
2.1.1.RELEASE
true
com.example.contractTest.BaseTestClass
import org.springframework.cloud.contract.spec.Contract
Contract.make {
request {
method('PUT')
headers {
contentType(applicationJson())
}
body(file("request.json"))
url("/1")
}
response {
status OK()
body(file("response.json"))
headers {
contentType(applicationJson())
}
}
}
上面那段配置我贴官网的。 在生成stub包的时候,你会发现有一个类叫ContractVerifierTest,这个是用来验证你的contract,它会继承BaseTestClass,所以当你的build失败,你打开ContractVerifierTest,debug里面的test case,然后就知道哪里有问题了。如果你的Contract里面的response body用了file 指向一个json文件,那么生成出来的 ContractVerifierTest对应的test case是没有response的字段校验的,所以你的响应数据要谨慎喔,这是小细节,你可以自己在ContractVerifierTest加校验,但是小心重新生成被覆盖。
干货来了,如果你在本地推你的contract到github的时候,如果你是用ssh的,但是又Auth Fail的字眼出现,这时你要检查你生成的公钥的时候是不是要输入密码的,如果你git clone代码的时候每次都要你输入密码,那就是这个问题所在的,你在生成密钥的时候不要输入密码直接回车过去就可以了。然后还是不行,那就用stackoverflow上面说的在你的git bash执行下面指令。这样应该可以过去了,我就是这样子过来的,我当初直接执行这个bash 脚本 ,不成功呀。就是因为设置了私钥的密码。如果你不用ssh当然你也可以用https形式推到github上面去,但是你要配置了
https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract-maven-plugin/
# to run the agent
$ eval `ssh-agent`
#to store the pass in the agent
ssh-add ~/.ssh/id_rsa
org.springframework.cloud
spring-cloud-contract-maven-plugin
${spring-cloud-contract.version}
true
git://[email protected]:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git
${project.groupId}
${project.artifactId}
${project.version}
REMOTE
package
pushStubsToScm
Producer你以为我已经结束了?还没有,在我推的那一刻,我发现还是失败了,报出generateTests failed: No stubs or contracts were found for[xxx]: and the switch to fail on no stubs was set.当我看到这个的时候,我内心是十万只草泥马。我看了一下日志,什么,他会去github上面拉代码,报了个can not access.原因是什么?下面是我的猜想,就git上面对应的版本号没有这个contract,所以他在download下来的时候报错,所以我用了另外一个方法,我先把stub包生成出来然后再执行pushStubsToScm goal,这个在maven插件Plugins下面会有。那生成的时候肯定不能用上面的配置,要换成推上nexus的那种配置生成stub。 在你的github仓库有了你相对应版本的contract的时候,你就可以用上面github的配置了。
org.springframework.cloud
spring-cloud-contract-maven-plugin
${spring-cloud-contract.version}
true
com.example.contractTest.BaseTestClass
Consumer端:
如果是使用REMOTE模式,你要在你的项目配置账号和密码,这样是不是很坑。这样安全吗,如果公司不考虑安全直接可以上,但是我公司不行呀,这样搞肯定不行啊,那他可读external的setting.xml文件吗,在社区上面还是一个被mark成enhancement。我也有曾想过encrypt,加密了放在那里,但是你总会有做解密的地方,java反编译,什么都看出来了。但是如果你公司不care,那没有关系的。直接在你properties文件配置stubrunner.username .stubrunner.password。还有一点,你的密码有没有过期的时候呢。
最后我想出了一个解决方案:就是直接在maven 里面把stub包加入成为依赖
最后:我是采取producer推上nexus,consumer在pom文件引入依赖的方式进来。原因:解决不用配置用户密码的问题,还有公司环境限制。写contract的时候少在uri用正则表达式,我用的版本如果在uri那里使用了正则,然后consumer端若对应的uri参数有问题会直接匹配到了actuator的/health,比较难找出问题。