Pengenalan Kontrak Spring Cloud

1. Perkenalan

Spring Cloud Contract adalah sebuah proyek yang, sederhananya, membantu kita menulis Kontrak yang Didorong Konsumen (CDC).

Ini memastikan kontrak antara Produsen dan Konsumen , dalam sistem terdistribusi - untuk interaksi berbasis HTTP dan berbasis pesan.

Dalam artikel singkat ini, kita akan mempelajari kasus pengujian sisi produsen dan konsumen untuk Spring Cloud Contract melalui interaksi HTTP.

2. Produser - Sisi Server

Kita akan menulis CDC sisi produsen, dalam bentuk EvenOddController - yang hanya memberi tahu apakah parameter angka genap atau ganjil:

@RestController public class EvenOddController { @GetMapping("/validate/prime-number") public String isNumberPrime(@RequestParam("number") Integer number) { return Integer.parseInt(number) % 2 == 0 ? "Even" : "Odd"; } }

2.1. Dependensi Maven

Untuk sisi produsen, kami memerlukan dependensi pemverifikasi kontrak pegas-cloud-starter :

 org.springframework.cloud spring-cloud-starter-contract-verifier 2.1.1.RELEASE test 

Dan kita perlu mengonfigurasi spring-cloud-contract-maven-plugin dengan nama kelas pengujian dasar kita, yang akan kita jelaskan di bagian selanjutnya:

 org.springframework.cloud spring-cloud-contract-maven-plugin 2.1.1.RELEASE true   com.baeldung.spring.cloud.springcloudcontractproducer.BaseTestClass   

2.2. Penyetelan Sisi Produsen

Kita perlu menambahkan kelas dasar dalam paket pengujian yang memuat konteks Spring kita:

@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) @DirtiesContext @AutoConfigureMessageVerifier public class BaseTestClass { @Autowired private EvenOddController evenOddController; @Before public void setup() { StandaloneMockMvcBuilder standaloneMockMvcBuilder = MockMvcBuilders.standaloneSetup(evenOddController); RestAssuredMockMvc.standaloneSetup(standaloneMockMvcBuilder); } }

Di / src / test / resources / contract / package, kami akan menambahkan stub pengujian , seperti yang ini di file shouldReturnEvenWhenRequestParamIsEven.groovy :

import org.springframework.cloud.contract.spec.Contract Contract.make { description "should return even when number input is even" request{ method GET() url("/validate/prime-number") { queryParameters { parameter("number", "2") } } } response { body("Even") status 200 } } 

Saat kami menjalankan build, plugin secara otomatis menghasilkan kelas pengujian bernama ContractVerifierTest yang memperluas BaseTestClass kami dan meletakkannya di / target / generated-test-sources / contract / .

Nama metode pengujian berasal dari awalan " validate_" yang digabungkan dengan nama stub pengujian Groovy kami. Untuk file Groovy di atas, nama metode yang dihasilkan adalah “validate_shouldReturnEvenWhenRequestParamIsEven” .

Mari kita lihat kelas pengujian yang dibuat secara otomatis ini:

public class ContractVerifierTest extends BaseTestClass { @Test public void validate_shouldReturnEvenWhenRequestParamIsEven() throws Exception { // given: MockMvcRequestSpecification request = given(); // when: ResponseOptions response = given().spec(request) .queryParam("number","2") .get("/validate/prime-number"); // then: assertThat(response.statusCode()).isEqualTo(200); // and: String responseBody = response.getBody().asString(); assertThat(responseBody).isEqualTo("Even"); } 

Build juga akan menambahkan stub jar di repositori Maven lokal kami sehingga dapat digunakan oleh konsumen kami.

Stubs akan ada di folder output di bawah stubs / mapping / .

3. Sisi Konsumen - Klien

Sisi konsumen CDC kami akan menggunakan rintisan yang dihasilkan oleh sisi produsen melalui interaksi HTTP untuk mempertahankan kontrak, sehingga setiap perubahan di sisi produsen akan melanggar kontrak .

Kami akan menambahkan BasicMathController, yang akan membuat permintaan HTTP untuk mendapatkan respons dari stub yang dihasilkan:

@RestController public class BasicMathController { @Autowired private RestTemplate restTemplate; @GetMapping("/calculate") public String checkOddAndEven(@RequestParam("number") Integer number) { HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.add("Content-Type", "application/json"); ResponseEntity responseEntity = restTemplate.exchange( "//localhost:8090/validate/prime-number?number=" + number, HttpMethod.GET, new HttpEntity(httpHeaders), String.class); return responseEntity.getBody(); } }

3.1. Dependensi Maven

Untuk konsumen kita, kita perlu menambahkan dependensi spring-cloud-contract-wiremock dan spring-cloud-contract-stub-runner :

 org.springframework.cloud spring-cloud-contract-wiremock 2.1.1.RELEASE test   org.springframework.cloud spring-cloud-contract-stub-runner 2.1.1.RELEASE test  

3.2. Pengaturan Sisi Konsumen

Sekarang saatnya untuk mengkonfigurasi stub runner kita, yang akan memberi tahu konsumen kita tentang stub yang tersedia di repositori Maven lokal kita:

@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) @AutoConfigureMockMvc @AutoConfigureJsonTesters @AutoConfigureStubRunner( stubsMode = StubRunnerProperties.StubsMode.LOCAL, ids = "com.baeldung.spring.cloud:spring-cloud-contract-producer:+:stubs:8090") public class BasicMathControllerIntegrationTest { @Autowired private MockMvc mockMvc; @Test public void given_WhenPassEvenNumberInQueryParam_ThenReturnEven() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/calculate?number=2") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string("Even")); } }

Perhatikan bahwa properti id dari anotasi @AutoConfigureStubRunner menentukan:

  • com.baeldung.spring.cloud - groupId artefak kita
  • spring-cloud-contract-producer - artefakId dari stoples rintisan produsen
  • 8090 - port tempat stub yang dihasilkan akan dijalankan

4. Saat Kontrak Rusak

Jika kami melakukan perubahan di sisi produsen yang berdampak langsung pada kontrak tanpa memperbarui sisi konsumen, hal ini dapat mengakibatkan kegagalan kontrak.

Misalnya, kita mengubah URI permintaan EvenOddController menjadi / validate / change / prime-number di sisi produsen kita.

Jika kami gagal memberi tahu konsumen kami tentang perubahan ini, konsumen akan tetap mengirim permintaannya ke / validate / prime-number URI, dan kasus uji sisi konsumen akan menampilkan org.springframework.web.client.HttpClientErrorException: 404 Not Found .

5. Ringkasan

Kami telah melihat bagaimana Kontrak Cloud Musim Semi dapat membantu kami mempertahankan kontrak antara konsumen layanan dan produsen sehingga kami dapat mengeluarkan kode baru tanpa khawatir melanggar kontrak.

Dan, seperti biasa, implementasi lengkap dari tutorial ini dapat ditemukan di GitHub.