Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

consumer_driven_contract with spring cloud contract at spring camp 2018

579 views

Published on

스프링캠프에서 발표한 세션내용입니다. http://www.springcamp.io/2018/
마이크로서비스가 본격적으로 확산이되면 API 제공자와 사용자간의 dependency가 생겨서 마이크로서비스 API의 개선과정이 매우 복잡해지고 느려지게됩니다. 이 문제를 해결하기 위해 Consumer Driven Contract기법을 적용한 Spring cloud contract 프로젝트의 활용방법에 대해 소개하고 샘플 애플리케이션을 통해 개발자들이 API를 개발하고 테스트하며 개선하는 방식에 대해 알아봅니다

Published in: Technology
  • Login to see the comments

consumer_driven_contract with spring cloud contract at spring camp 2018

  1. 1. 김민석 (myminseok@gmail.com) Pivotal 1 Consumer Driven Contract 기법을 활용하여 마이크로서비스들의 API를 안전하게 진화시키는 방법
  2. 2. Spring Camp 2018 2 소개 •  김민석 (myminseok@gmail.com) •  Platform Architect @ Pivotal •  Big-Data Monitoring System Developer •  Software Architect •  Software Quality Engineer •  Developer https://www.facebook.com/groups/CloudfoundryKorea
  3. 3. Spring Camp 2018 3 Message from Marcin Spring Cloud developer at Pivotal working mostly on ●  Spring Cloud Sleuth ●  Spring Cloud Contract ●  Spring Cloud Pipelines Connect with me ●  Twitter: @mgrzejszczak ●  Blog: http://toomuchcoding.com
  4. 4. Spring Camp 2018 4 목차 1.  Agile, MSA, 새로운 문제들 2.  안전한 API 진화를 위한 패턴 3.  Spring Cloud Contract 4.  Demo 5.  Q&A
  5. 5. Agile, MSA 그리고 새로운 문제들
  6. 6. Spring Camp 2018 6 Netflix
  7. 7. Spring Camp 2018 7 마이크로서비스에서의 API란?
  8. 8. Spring Camp 2018 8 API 개선 라이프사이클 API consumer API Producer Consumer의 Feedback 수렴 API (Contact) 설계 및 공유
  9. 9. Spring Camp 2018 9 개발/테스트/서비스반영 API consumer API Producer API 개선 라이프사이클
  10. 10. Spring Camp 2018 10 우리의 IT환경은 점점 •  마이크로 서비스팀이 점점 작아지고 많아짐 •  API contract 개선이 더 잦아짐(Agile) •  다른 시간대(Timezone)의 팀간의 협업이 요구됨
  11. 11. Spring Camp 2018 11 풀기 어려운 문제 1.  Consumer에 영향없이 Producer서비스에 새로운 것을 추가하거나 삭제할 수 있을까? 2.  Consumer가 Producer서비스를 어떻게 사용하고 있는지를 Producer서비스 개발자가 알 수 있을까? 3.  Producer서비스의 릴리즈 사이클을 짧게 할 수 있을까?
  12. 12. Spring Camp 2018 12 웹서비스 진화를 위한 패턴 •  Single Message Argument •  Dataset Amendment •  Tolerant Reader •  Schema Versioning •  Consumer-Driven Contracts http://www.servicedesignpatterns.com/WebServiceEvolution
  13. 13. Consumer Driven Contracts
  14. 14. Spring Camp 2018 14Source: http://martinfowler.com/articles/consumerDrivenContracts.html CDC는 Consumer의 요구사항 중심으로 Producer 서비스를 진화하기 위한 협업 패턴
  15. 15. Spring Camp 2018 15 Consumer Driven Contracts의 장점 •  Producer는 불필요한 서비스 개발을 줄일 수 있음 (make the right thing) •  Producer는 개선에 대한 통찰을 얻을 수 있음 •  Agile실현을 위한 자동화을 가속화함
  16. 16. Spring Camp 2018 16 Consumer Driven Contracts가 성공하려면 Contract(API) 스펙 정의 API 문서화 REST API 테스트 API스펙과 일치하는 테스트코드 유지 API동작을 모니터링/제어 API Gateway Consumer Driven Contract의 핵심은 커뮤니케이션
  17. 17. Spring Camp 2018 17 API 관리도구 Contract(API) 스펙 정의 REST API 테스트 API 문서화 API 운영 도구 API스펙과 일치하는 코드유지 ? ? ? ?
  18. 18. 내가 작성한 코드가 API 스펙과 일관성이 있는가?
  19. 19. Spring Camp 2018 19 End-to-end 테스트전략은 확실하나 비효율적 •  모든 마이크로서비스를 배포하여 환경을 구성 •  실제 환경과 유사 •  테스트 자원 소모 •  긴 환경 준비시간 •  느린 feedback(실행시간) •  debug가 어렵다
  20. 20. Spring Camp 2018 20 Mock(Stub)을 활용하는 테스트 전략이 일반적 •  빠른 feedback •  적은 테스트 자원필요 •  테스트가 통과하더라도 실제 서비스에서 실패할 수 있음
  21. 21. Spring Camp 2018 21 Mock(Stub)을 활용한 테스트코드의 작성 API consumer API Producer Producer TestCase Producer TestCase API (Contact) 스펙 문서
  22. 22. Spring Camp 2018 22 테스트가 성공해도 실제 서비스는 실패할 수 있다. API consumer API Producer Producer TestCase Producer TestCase API (Contact) 스펙 문서
  23. 23. Spring Camp 2018 23 Consumer의 코드는 •  Contract(API)와 정합성을 보장하는 메커니즘이 없음 •  JSON 데이터파일의 최신상태 관리의 어려움
  24. 24. Spring Camp 2018 24 Contract(API) 스펙 정의 API 문서화 REST API 테스트 API스펙과 일치하는 테스트코드 유지 API동작을 모니터링/제어 API Gateway Consumer Driven Contract의 핵심은 커뮤니케이션 Consumer Driven Contracts가 성공하려면 contract와 정합성을 보장하는 메커니즘이 필요
  25. 25. Spring Cloud Contract
  26. 26. Spring Camp 2018 26 Spring Cloud Contract 목표 1. Contract를 공유하는 메커니즘을 제공 (Consumer Driven Contract) - 정의하고 읽기 쉬운 형태로 Contract 형식(DSL) - REST, Messaging 지원 2. Contract를 적용할 때 자동화를 통해 확신을 주자 -  Producer는 Contract를 만족하는 Producer Stubs를 자동 생, Producer테스트에 활용 -  Consumer의 테스트코드는 Producer가 테스트에 활용한 그 stub을 다 운로드, stub은 정합성이 보장 -  서비스로 넘어가기전에 Fail-Fast
  27. 27. Spring Camp 2018 27 Spring Cloud Contract Maven Plugin Spring cloud Contract verifier <dependency> <groupId>org.Springframework.cloud</groupId> <artifactId>Spring-cloud-starter-contract-verifier</artifactId> <scope>test</scope> </dependency> Spring cloud Contract stub runner <dependency> <groupId>org.Springframework.cloud</groupId> <artifactId>Spring-cloud-contract-stub-runner</artifactId> <scope>test</scope> </dependency>
  28. 28. Spring Camp 2018 28 Contract로 부터 자동으로 stub.jar 생성 $ mvn clean install OutputsReads Producer테스트용 Junit 테스트케이스 Contract.make { request{ url "/check" method POST() body( age: value(regex('[2-9][0-9]'))) headers{ contentType(applicationJson()) } } response{ status 200 body(""" {"status": "OK" } "””) } Producer-stub.jar •  Contract정의파일 •  Wiremock stub 정의(json)
  29. 29. Spring Camp 2018 29 Consumer는 자동으로 stub을 내려받아 Mock서버를 생성 Producer-stub.jar Spring-cloud-contract-stub-runner 자동 다운로드 @RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureWireMock @AutoConfigureStubRunner(workOffline=true, ids="com.example:beer-server:+:stubs:8081") public class BeerClientApplicationTests { @Test public void old_enough_stubs() { … }
  30. 30. Spring Camp 2018 30 Spring Cloud Contract workflow Contract 정의/테스트 (stub runner offline mode) Contract 구현/테스트 Contract stubs.jar 자동생성 (sub runner offline mode) Contract 정의 Pull Request Consumer Project Producer Project stub.jar 업로드 Stub.jar 자동 다운로드 Contract stubs.jar를 이용한 consumer테스트 (stub runner online mode)
  31. 31. Spring Camp 2018 31 활용 시나리오 데모 1.  기본동작 2.  Stateful 시나리오 지원 3.  Stub을 Mock Server로 실행하기 4.  Spring cloud 지원 5.  Contract 파일 관리 방안 6.  다양한 언어 지원 7.  PACT 파일 지원 8.  Spring cloud pipeline에 활용
  32. 32. Demo#1 기본동작 32
  33. 33. Spring Camp 2018 33 기본 데모 구성 POST /check {age=22} Local Maven Repo Contract.make { request { … } response { … } } Stub등록 Beer-client project Beer-server project consumer ProducerBeer-server-stub.jar { “status”: “OK”} https://github.com/myminseok/Spring-cloud-contract-beer-sample
  34. 34. Spring Camp 2018 34 Groovy, YML형식의 DSL 제공 Contract의 정의 request: method: POST url: /check body: “age”: 22 headers: Content-Type: application/json matchers: body: - path: $.[’age'] type: by_regex value: ”[2-9][0-9]" response: status: 200 body: status: ”OK” Contract.make { request{ url "/check" method POST() body( age: value(regex('[2-9][0-9]'))) headers{ contentType(applicationJson()) } } response{ status 200 body(""" {"status": "OK" } "””) }
  35. 35. Demo#2 Stub을 Mock Server로 실행하기 35
  36. 36. Spring Camp 2018 36 Stub을 Mock Server로 실행하기 Stub runner boot ConsumerStub-runner.jar 80818080 REMOTE, LOCAL, CLASSPATH $ java -jar stub-runner.jar --stubrunner.ids=com.example:beer-server:+:stubs:8081 --stubrunner.workOffline=true http://localhost:8081/__admin https://github.com/myminseok/Spring-cloud-contract-beer-sample
  37. 37. Demo#3 Stateful 시나리오 지원 37
  38. 38. Spring Camp 2018 38 State-machine처럼 이전상태에 기반한 상태전이 테스트가 가능 Consumer SOBER Producer stub TIPSY Drunk curl X POST localhost/beer => {"currentStatus":"TIPSY","previousStatus":"SOBER”} curl X POST localhost/beer => {"currentStatus":”DRUNK","previousStatus":"TIPSY”} WASTED curl X POST localhost/beer => {"currentStatus":”WASTED","previousStatus":”DRUNK”} https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/master/ producer
  39. 39. Spring Camp 2018 39 시나리오 순서대로 Contract를 정의 request { method 'POST' url '/beer' body( name: "marcin”) } response { status 200 body( previousStatus: "SOBER", currentStatus: "TIPSY" ) request { method 'POST' url '/beer' body( name: "marcin”) } response { status 200 body( previousStatus: "TIPSY", currentStatus: "DRUNK" )
  40. 40. Spring Camp 2018 40 자동생성된 stub, Spring cloud contract wiremock을 통해 작동 Wiremock의 stateful기능 기반의 JSON 자동생성 { "request" : { "url" : "/beer", }, "bodyPatterns" : [ { "matchesJsonPath" : "$[?(@.['name'] == 'marcin')]" } ] }, "response" : { "status" : 200, "body" : "{"currentStatus":"TIPSY", "previousStatus":"SOBER"}", "uuid" : "2690ba56-b024-4de5-9492-33c37c2d9208", "scenarioName" : "Scenario_intoxication", "requiredScenarioState" : "Started", "newScenarioState" : "Step1" }
  41. 41. Demo#4 Spring cloud 지원 41
  42. 42. Spring Camp 2018 42 Spring cloud를 연동하는 프로젝트 지원
  43. 43. Spring Camp 2018 43 Spring cloud를 연동하는 테스트케이스 지원 Beer-client-controller.java ResponseEntity<Response> response = this.restTemplate.exchange( RequestEntity .post(URI.create("http://beer-api-from-eureka/check")) .body(person), Response.class); 테스트 코드 @@AutoConfigureMockMvc public class BeerControllerTest { Stub runner boot beer-api-from-eureka https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/master/ consumer_with_discovery
  44. 44. Spring Camp 2018 44 Spring cloud를 연동하는 테스트케이스 지원 Beer-client-controller.java stubrunner: idsToServiceIds: beer-api-stub: beer-api-from-eureka Test/ applicaton.yml ResponseEntity<Response> response = this.restTemplate.exchange( RequestEntity .post(URI.create("http://beer-api-from-eureka/check")) .body(person), Response.class); 테스트 코드 @@AutoConfigureMockMvc @AutoConfigureStubRunner(workOffline = true, ids = "com.example:beer-api-stub") public class BeerControllerTest { Stub runner boot beer-api-from-eureka beer-api-stub
  45. 45. Spring Camp 2018 45 Spring cloud eureka에 stub자동등록 지원 Stub runner boot Spring cloud Stub runner boot eureka에 stub들을 자동으로 등록 Stub runner boot API호출 Consumer https://github.com/Spring-cloud-samples/github-analytics-stub-runner-boot
  46. 46. Spring Camp 2018 46 import org.Springframework.cloud.contract.stubrunner.server.EnableStubRunnerServer; import org.Springframework.cloud.contract.stubrunner.Spring.AutoConfigureStubRunner; @SpringBootApplication @EnableStubRunnerServer @EnableEurekaClient public class StubrunnereurekaApplication { public static void main(String[] args) { SpringApplication.run(StubrunnereurekaApplication.class, args); } @AutoConfigureStubRunner static class Config {} } 커스텀 Stubrunner app
  47. 47. Demo#5 Contract파일 관리방안 47
  48. 48. Spring Camp 2018 48 방안1: Contract파일을 Producer 프로젝트에 포함 •  Producer가 주도적으로 관리 •  (보안)정책상 Consumer가 Producer 프로젝트에 접근하기 어려울수 있음
  49. 49. Spring Camp 2018 49 방안2: Consumer와 Producer가 접근할 수 있는 공통의 프로젝트 구성 Contract Project -  Contract 파일 관리 -  maven-assembly-plugin 빌드 Producer Project -  Pom.xml에 contractDependency 설정 <plugin> <artifactId>Spring-cloud-contract-maven-plugin <configuration> <contractDependency> <groupId>com.example</groupId> <artifactId>beer-contracts</artifactId> </contractDependency> https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/master/ beer_contracts
  50. 50. Demo#6 다양한 언어 지원 50
  51. 51. Spring Camp 2018 51 maven JAVA Docker 다양한 언어의 서비스에 대해 stub생성지원 Polygot 언어지원 $ docker pull Springcloud/Spring-cloud-contract /contracts Spring Cloud Contractread https://github.com/Spring-cloud-samples/Spring-cloud-contract-nodejs -stub.jar nodeJS app
  52. 52. Demo#7 PACT 파일 지원 52
  53. 53. Spring Camp 2018 53 Groovy DSL PACT 지원 Contract.make { request{ url "/check" method POST() body( age: value(regex('[2-9][0-9]'))) headers{ contentType(applicationJson()) } } response{ status 200 body(""" {"status": "OK" } "””) } PACT DSL { “interactions”: [ “request”: { path: “/check”, method: “POST”, "body": { "age": "22" }, “matchingRules”: { header{ … } body: { "$.age": { “matchers”: [ { "match": "regex", "regex": "[2-9][0-9] }]} } }, “response”: {
  54. 54. Spring Camp 2018 54 PACT파일을 활용하여 stub과 테스트케이스 생성가능 Spring cloud contract Pact plugin추가 <plugin> <groupId>org.Springframework.cloud</groupId> <artifactId>Spring-cloud-contract-maven-plugin</artifactId> <dependencies> <dependency> <groupId>org.Springframework.cloud</groupId> <artifactId>Spring-cloud-contract-spec-pact</artifactId> <version>1.2.4.RELEASE</version> </dependency> <dependency> <groupId>au.com.dius</groupId> <artifactId>pact-jvm-model</artifactId> <version>2.4.18</version>
  55. 55. Demo#8 Spring Cloud Pipeline 55
  56. 56. Spring Camp 2018 56 Spring cloud pipeline에 활용 https://github.com/Spring-cloud/Spring-cloud-pipelines
  57. 57. Spring Camp 2018 57 Spring cloud pipeline에 활용
  58. 58. Spring Camp 2018 58 Spring cloud pipeline에 활용 •  의존성이 있는 service를 실제로 구성할 필요 없음(stub runner활용) •  테스트 속도 증가 •  PaaS플랫폼과 연계하여 테스트 환경구성 자동화
  59. 59. Demo#9 Messaging 지원 59
  60. 60. Spring Camp 2018 60 Messaging 지원 Contract.make { label 'accepted_verification' input { triggeredBy('clientIsOldEnough()') } outputMessage { sentTo 'verifications' body( eligible: true ) headers { header("contentType", applicationJsonUtf8()) } } Producer프로젝트: - Spring-cloud-stream-test-support Consumer프로젝트: Spring-cloud-stream-test-support Spring-cloud-starter-stream-rabbit Spring-cloud-starter-contract-stub-runner •  Apache Camel •  Spring Integration •  Spring Cloud Stream •  Spring AMQP 필요한 dependency
  61. 61. Spring Camp 2018 61 Summary Consumer Driven Contract패턴을 지원하는 Spring Cloud Contract를 활용하여 마이크로서비스 API를 안전하게 개선 •  Contract 스펙정의에 필요한 도구 제공 •  Contract를 만족하는 Producer Stubs를 자동 생성 •  Consumer는 Producer 서비스 테스트에 활용한 그 stub을 사용(일관성) •  Stub 패턴을 활용하여 의존성이 있는 service를 배포할 필요없고 빠른 feedback제공(failfast) •  테스트 파이프라인에 쉽게 적용, 테스트 자동화 가능 •  Dependency가 복잡한 마이크로 서비스 테스트에 효과적 •  contract를 개선할 때 Producer /Consumer조율 시간과 비용을 줄일 수 있음
  62. 62. Spring Camp 2018 62 Learn More. Stay Connected. ▪  데모샘플 https://github.com/myminseok/Spring-cloud-contract-beer-sample ▪  Read the docs http://cloud.Spring.io/Spring-cloud-contract/ ▪  Talk to us on Gitter https://gitter.im/Spring-cloud/Spring-cloud-contract Twitter: twitter.com/Springcentral YouTube: Spring.io/video LinkedIn: Spring.io/linkedin Google Plus: Spring.io/gplus
  63. 63. Q&A 63

×