Spring Cloud’s Groovy

37
Spring Cloud’s Groovy Marcin Grzejszczak, Pivotal @mgrzejszczak

Transcript of Spring Cloud’s Groovy

Page 1: Spring Cloud’s Groovy

Spring Cloud’s Groovy

Marcin Grzejszczak, Pivotal@mgrzejszczak

Page 2: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

About meDeveloper at Pivotal

Part of Spring Cloud Team

Working with OSS

TWITTER: @MGrzejszczak

BLOG: TOOMUCHCODING.COM

Page 3: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

AgendaWhat are we using Groovy for at Spring Cloud?

Quick introduction to Distributed Tracing

Why Gradle made it possible to test Spring Cloud?

How we’re testing with Spock?

DEMO

Page 4: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

AgendaWhat are we using Groovy for at Spring Cloud?

Quick introduction to Distributed Tracing

Why Gradle made it possible to test Spring Cloud?

How we’re testing with Spock?

DEMO

Page 5: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

What are we using Groovy for at Spring Cloud?Spring Cloud Zookeeper tests with Spock

End to end tests of Spring Cloud

Zookeeper

Consul

Eureka

Netflix (Zuul, Ribbon, Feign)

Sleuth

Page 6: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

What are we using Groovy for at Spring Cloud?Spring Cloud Zookeeper tests with Spock

End to end tests of Spring Cloud

Zookeeper

Consul

Eureka

Netflix (Zuul, Ribbon, Feign)

Sleuth

Page 7: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

AgendaWhat are we using Groovy for at Spring Cloud?

Quick introduction to Distributed Tracing

Why Gradle made it possible to test Spring Cloud?

How we’re testing with Spock?

DEMO

Page 8: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Quick Introduction To Distributed TracingModern applications are a gigantic net of interconected components

It’s crucial to have tools that allow you visualize the system’s topology and performance issues

Dapper, a Large-Scale Distributed Systems Tracing Infrastructure

Page 9: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Quick Introduction To Distributed TracingZipkin

A distributed tracing system.

Helps gather timing data needed to troubleshoot latency problems in microservice architectures

The front end is a "waterfall" style graph of service calls showing call durations as horizontal bars

Page 10: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Quick Introduction To Distributed TracingSpring Cloud Sleuth

Implements a distributed tracing solution for Spring Cloud.

Borrows Dapper’s terminology.

Integrates with Zipkin

Page 11: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

TerminologySpan

The basic unit of work (e.g. sending RPC)

Spans are started and stopped

They keep track of their timing information

Once you create a span, you must stop it at some point in the future

Page 12: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

TerminologyTrace

A set of spans forming a tree-like structure.

For example, if you are running a book store then a trace could be retriving a list of available books

Page 13: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Terminology

SERVICE 1

REQUEST

No Trace IdNo Span Id

RESPONSE

SERVICE 2

SERVICE 3

Trace Id = XSpan Id = A

Trace Id = XSpan Id = A

Trace Id = XSpan Id = A

REQUEST

RESPONSE

Trace Id = XSpan Id = BClient Sent

Trace Id = XSpan Id = B

Client Received

Trace Id = XSpan Id = B

Server Received

Trace Id = XSpan Id = C

Trace Id = XSpan Id = BServer Sent

REQUEST

RESPONSE

Trace Id = XSpan Id = DClient Sent

Trace Id = XSpan Id = D

Client Received

Trace Id = XSpan Id = D

Server Received

Trace Id = XSpan Id = E

Trace Id = XSpan Id = DServer Sent

Trace Id = XSpan Id = E

SERVICE 4

REQUEST

RESPONSE

Trace Id = XSpan Id = FClient Sent

Trace Id = XSpan Id = F

Client Received

Trace Id = XSpan Id = F

Server Received

Trace Id = XSpan Id = G

Trace Id = XSpan Id = FServer Sent

Trace Id = XSpan Id = G

Trace Id = XSpan Id = C

Page 14: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Terminology

Span Id = AParent Id = null

Span Id = BParent Id = A

Span Id = CParent Id = B

Span Id = DParent Id = C

Span Id = EParent Id = D

Span Id = FParent Id = C

Span Id = GParent Id = F

Page 15: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Terminology

SERVICE 1/start

REQUEST

No Trace IdNo Span Id

RESPONSE

SERVICE 2/foo

SERVICE 3/bar

Trace Id = XSpan Id = A

Trace Id = XSpan Id = A

Trace Id = XSpan Id = A

REQUEST

RESPONSE

Trace Id = XSpan Id = BClient Sent

Trace Id = XSpan Id = B

Client Received

Trace Id = XSpan Id = B

Server Received

Trace Id = XSpan Id = C

Trace Id = XSpan Id = BServer Sent

REQUEST

RESPONSE

Trace Id = XSpan Id = DClient Sent

Trace Id = XSpan Id = D

Client Received

Trace Id = XSpan Id = D

Server Received

Trace Id = XSpan Id = E

Trace Id = XSpan Id = DServer Sent

Trace Id = XSpan Id = E

SERVICE 4/baz

REQUEST

RESPONSE

Trace Id = XSpan Id = FClient Sent

Trace Id = XSpan Id = F

Client Received

Trace Id = XSpan Id = F

Server Received

Trace Id = XSpan Id = G

Trace Id = XSpan Id = FServer Sent

Trace Id = XSpan Id = G

Trace Id = XSpan Id = C

Page 16: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Terminology

Page 17: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Terminology

Page 18: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

AgendaWhat are we using Groovy for at Spring Cloud?

Quick introduction to Distributed Tracing

Why Gradle made it possible to test Spring Cloud?

How we’re testing with Spock?

DEMO

Page 19: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Why Gradle made it possible to test Spring Cloud?What we wanted to achieve:

apart from having good unit / integration tests we wanted to see all building blocks working together

we didn’t want to write different test apps for different libraries

we wanted to write a solution that could test the libs on Cloud Foundry (PaaS by Pivotal)

we wanted to prove that Spring Cloud’s Service Discovery integration is all about changing jars and configs

Page 20: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Page 21: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Page 22: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Why Gradle made it possible to test Spring Cloud?What do we want to test?

service discovery is working - apps can talk to each other

via RestTemplatevia Feign

Sleuth is working

proper spans were createdtrace information got propagated

Page 23: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Why Gradle made it possible to test Spring Cloud?change the apps building blocks by properties:

Page 24: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Why Gradle made it possible to test Spring Cloud?package apps with desired building blocks

./gradlew clean build --parallel -DWHAT_TO_TEST=CONSUL

./gradlew clean build --parallel -DWHAT_TO_TEST=EUREKA

./gradlew clean build --parallel -DWHAT_TO_TEST=SLEUTH

Page 25: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Why Gradle made it possible to test Spring Cloud?create Dockerfiles by executing a closure

Page 26: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Why Gradle made it possible to test Spring Cloud?clear separation of configurations

Page 27: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Why Gradle made it possible to test Spring Cloud?$ ./runAcceptanceTests.sh

USAGE:

You can use the following options:

-t|--whattotest - define what you want to test (e.g. SLEUTH, ZOOKEEPER)

-v|--version - which version of BOM do you want to use? Defaults to Brixton snapshot

-h|--healthhost - what is your health host? where is docker? defaults to localhost

-l|--numberoflines - how many lines of logs of your app do you want to print? Defaults to 1000

-r|--reset - do you want to reset the git repo of brewery? Defaults to "no"

-k|--killattheend - should kill all the running apps at the end of execution? Defaults to "no"

-n|--killnow - should not run all the logic but only kill the running apps? Defaults to "no"

-x|--skiptests - should skip running of e2e tests? Defaults to "no"

-s|--skipbuilding - should skip building of the projects? Defaults to "no"

-c|--cloudfoundry - should run tests for cloud foundry? Defaults to "no"

-o|--deployonlyapps - should deploy only the brewery business apps instead of the infra too? Defaults to "no"

-d|--skipdeployment - should skip deployment of apps? Defaults to "no"

Page 28: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

AgendaWhat are we using Groovy for at Spring Cloud?

Quick introduction to Distributed Tracing

Why Gradle made it possible to test Spring Cloud?

How we’re testing with Spock?

DEMO

Page 29: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

How we’re testing with Spock?we wanted to

run same tests for Cloud Foundry and locally

run the same tests with different libraries used

only execute related tests

Page 30: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

How we’re testing with Spock?@Requires({ TestConditions.SLEUTH() })

class SleuthBreweryAcceptanceSpec extends AbstractBreweryAcceptanceSpec {

@Unroll

def 'should successfully pass Trace Id via [#communicationType] and processId [#referenceProcessId]'() {

given:

RequestEntity requestEntity = an_order_for_all_ingredients_with_process_id(referenceProcessId, communicationType)

when: 'the presenting service has been called with all ingredients'

presenting_service_has_been_called(requestEntity)

then: 'eventually beer will be brewed with same Trace-Id as the first request'

beer_has_been_brewed_for_process_id(referenceProcessId)

and: 'entry will be present in Zipkin'

entry_for_trace_id_is_present_in_Zipkin(referenceProcessId)

where:

communicationType << [CommunicationType.REST_TEMPLATE, CommunicationType.FEIGN]

referenceProcessId = Span.idToHex(new Random().nextLong())

}

}

Page 31: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

How we’re testing with Spock?

static final Closure<Boolean> SLEUTH = {

return whatToTestSystemPropMatchesAny(

[WhatToTest.SLEUTH, WhatToTest.SLEUTH_STREAM]

)

}

Page 32: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

How we’re testing with Spock?

Page 33: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Page 34: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

AgendaWhat are we using Groovy for at Spring Cloud?

Quick introduction to Distributed Tracing

Why Gradle made it possible to test Spring Cloud?

How we’re testing with Spock?

DEMO

Page 35: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

DEMO

Page 36: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

SummaryGradle allowed to create highly customizable project just by changing a property

With Groovy and Spock we’ve managed to create a test setup that is readable and platform-independant

Even though they are hard to debug - with E2E we’ve managed to find quite a few bugs already

Page 37: Spring Cloud’s Groovy

@MGrzejszczak @gr8day_warsaw#GR8DayWAW

Thank You!Sleuth Repo & Docs:

https://github.com/spring-cloud/spring-cloud-sleuth

http://cloud.spring.io/spring-cloud-sleuth/spring-cloud-sleuth.html

The Brewery

https://github.com/spring-cloud-samples/brewery

Rationale behind E2E tests

https://spring.io/blog/2016/01/04/testing-spring-cloud-projects