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文件引入依賴的方式進來。原因:解決不用配置用戶密碼的問題,還有公司環境限制。


分享到:


相關文章: