Spring Cloud Contract 爬坑记

前言: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

<code><plugins>  <plugin>  <groupid>org.springframework.cloud/<groupid>  <artifactid>spring-cloud-contract-maven-plugin/<artifactid>  <version>2.1.1.RELEASE/<version>  <extensions>true/<extensions>  <configuration>  <baseclassfortests>com.example.contractTest.BaseTestClass/<baseclassfortests>  /<configuration>/<plugin>/<plugins>/<code>


<code>import org.springframework.cloud.contract.spec.ContractContract.make {  request {  method('PUT')  headers {  contentType(applicationJson())  }  body(file("request.json"))  url("/1")}response {    status OK()    body(file("response.json"))    headers {      contentType(applicationJson())    }  }}/<code>

上面那段配置我贴官网的。 在生成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上面去,但是你要配置了<contractsrepositoryusername>和<contractsrepositorypassword>,下面是spring-cloud-contract-maven-plugin的配置你值得收藏。如果你用百度搜索你会很容易GG的,建议用bing,能健康上网,那当然用google。/<contractsrepositorypassword>/<contractsrepositoryusername>

https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract-maven-plugin/

<code># to run the agent$ eval `ssh-agent`#to store the pass in the agentssh-add ~/.ssh/id_rsa/<code>
<code><plugin>  <groupid>org.springframework.cloud/<groupid>  <artifactid>spring-cloud-contract-maven-plugin/<artifactid>  <version>${spring-cloud-contract.version}/<version>  <extensions>true/<extensions><configuration>      <contractsrepositoryurl>git://[email protected]:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git/<contractsrepositoryurl>    <contractdependency>  <groupid>${project.groupId}/<groupid>  <artifactid>${project.artifactId}/<artifactid>  <version>${project.version}/<version>/<contractdependency><contractsmode>REMOTE/<contractsmode>/<configuration><executions>  <execution>    <phase>package/<phase>    <goals>                  <goal>pushStubsToScm/<goal>    /<goals>  /<execution>/<executions>/<plugin>/<code>

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的配置了。

<code>     <plugin>        <groupid>org.springframework.cloud/<groupid>        <artifactid>spring-cloud-contract-maven-plugin/<artifactid>        <version>${spring-cloud-contract.version}/<version>        <extensions>true/<extensions>        <configuration>            <baseclassfortests>com.example.contractTest.BaseTestClass/<baseclassfortests>        /<configuration>    /<plugin>/<code>

Consuer端:

如果是使用REMOTE模式,你要在你的项目配置账号和密码,这样是不是很坑。这样安全吗,如果公司不考虑安全直接可以上,但是我公司不行呀,这样搞肯定不行啊,那他可读external的setting.xml文件吗,在社区上面还是一个被mark成enhancement。我也有曾想过encrypt,加密了放在那里,但是你总会有做解密的地方,java反编译,什么都看出来了。但是如果你公司不care,那没有关系的。直接在你properties文件配置stubrunner.username .stubrunner.password。还有一点,你的密码有没有过期的时候呢。

最后我想出了一个解决方案:就是直接在maven 里面把stub包加入成为依赖<scope>为test。然后运行模式换成CLASSPATH.哈哈这样就可以了吧,这里要注意stub包的版本要最新的,不然别人改了接口,重新发布,你拿的还是旧的contract,上生产的时候你就GG了,不过这样通常在做联调测试的时候会被发现。要是没发现那真的是GG了。怎么保持stub版本最新,这里运用到maven version的版本控制的小技巧, <version>LATEST/<version>,我就让他拿最新的,当然你也可以控制他只拿[1,+)即>=1.0的版本。这个方案有不好地方,就是依赖了很多无用的包进来项目,如果contract太多会导致包臃肿过大,还会有包的冲突的问题。要自己去exclude。/<scope>

最后:我是采取producer推上nexus,consumer在pom文件引入依赖的方式进来。原因:解决不用配置用户密码的问题,还有公司环境限制。


分享到:


相關文章: