217
Tools, techniques and reflections BDD-Driven Microservices in Java

BDD-Driven Microservices

Embed Size (px)

Citation preview

Page 1: BDD-Driven Microservices

Tools, techniques and reflections

BDD-Driven Microservices in Java

Page 2: BDD-Driven Microservices

John Ferguson

Smart

Introductions“I help teams of smart people

learn to work together more efficiently, to deliver better software faster”

Page 3: BDD-Driven Microservices

Independently Deployable

Bounded ContextsLoosely CoupledSingle Responsibility

Microservices 101

Page 4: BDD-Driven Microservices

Independently Deployable

Bounded ContextsLoosely CoupledSingle Responsibility

Microservices 101

Page 5: BDD-Driven Microservices

Independently Deployable

Bounded ContextsLoosely CoupledSingle Responsibility

Microservices 101

Page 6: BDD-Driven Microservices

Independently Deployable

Bounded ContextsLoosely CoupledSingle Responsibility

Microservices 101

Page 7: BDD-Driven Microservices

Independently Deployable

Bounded ContextsLoosely CoupledSingle Responsibility

Microservices 101

Page 8: BDD-Driven Microservices

Independently Deployable

Bounded ContextsLoosely CoupledSingle Responsibility

Microservices 101

Page 9: BDD-Driven Microservices

Microservices 101

Movie Catalog Service

Authentication Service

Shopping Cart Service

Delivery Service

Payment Service

REST/HTTP

Page 10: BDD-Driven Microservices

Microservices 101

Movie Catalog Service

Authentication Service

Shopping Cart Service

Delivery Service

Payment Service

Event Bus

Page 11: BDD-Driven Microservices

Microservices 101Movie Catalog Service

Page 12: BDD-Driven Microservices

Microservices 101Movie Catalog Service

Resource

Page 13: BDD-Driven Microservices

Microservices 101Movie Catalog Service

Resource

Service Layer

Domain model

Repositories

Page 14: BDD-Driven Microservices

Microservices 101Movie Catalog Service

Resource

Persistance Layer

Service Layer

Domain model

Repositories

Page 15: BDD-Driven Microservices

Microservices 101Movie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Page 16: BDD-Driven Microservices

The testing pyramid

Page 17: BDD-Driven Microservices

The testing pyramid

Unit Tests

Page 18: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

Page 19: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 20: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 21: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 22: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 23: BDD-Driven Microservices

The testing pyramidMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Unit Tests

Page 24: BDD-Driven Microservices

The testing pyramidMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Unit Tests

Page 25: BDD-Driven Microservices

The testing pyramidMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Unit Tests

Page 26: BDD-Driven Microservices

The testing pyramidMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Unit Tests

Page 27: BDD-Driven Microservices

The testing pyramidMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Unit Tests

Page 28: BDD-Driven Microservices

The testing pyramidMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Unit Tests

Page 29: BDD-Driven Microservices

The testing pyramidMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Unit Tests

Page 30: BDD-Driven Microservices

The testing pyramidMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Unit Tests

Page 31: BDD-Driven Microservices

The testing pyramidMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Unit Tests

Page 32: BDD-Driven Microservices

The testing pyramidMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Integration Tests

Page 33: BDD-Driven Microservices

The testing pyramidMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Integration Tests

Page 34: BDD-Driven Microservices

The testing pyramidMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Integration Tests

Page 35: BDD-Driven Microservices

The testing pyramidMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Integration Tests

Page 36: BDD-Driven Microservices

The testing pyramidMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Integration Tests

Page 37: BDD-Driven Microservices

The testing pyramid End-to-End Tests

Movie Catalog Service

Authentication Service

Shopping Cart Service

Delivery Service

Payment Service

Event Bus

Page 38: BDD-Driven Microservices

The testing pyramid End-to-End Tests

Movie Catalog Service

Authentication Service

Shopping Cart Service

Delivery Service

Payment Service

Event Bus

Page 39: BDD-Driven Microservices

The testing pyramid End-to-End Tests

Movie Catalog Service

Authentication Service

Shopping Cart Service

Delivery Service

Payment Service

Event Bus

Page 40: BDD-Driven Microservices

The testing pyramid End-to-End Tests

Movie Catalog Service

Authentication Service

Shopping Cart Service

Delivery Service

Payment Service

Event Bus

Page 41: BDD-Driven Microservices

The testing pyramid End-to-End Tests

Movie Catalog Service

Authentication Service

Shopping Cart Service

Delivery Service

Payment Service

Event Bus

Page 42: BDD-Driven Microservices

The testing pyramid End-to-End Tests

Movie Catalog Service

Authentication Service

Shopping Cart Service

Delivery Service

Payment Service

Event Bus

Page 43: BDD-Driven Microservices

The testing pyramid End-to-End Tests

Movie Catalog Service

Authentication Service

Shopping Cart Service

Delivery Service

Payment Service

Event Bus

Page 44: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 45: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 46: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 47: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 48: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 49: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 50: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 51: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 52: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 53: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 54: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 55: BDD-Driven Microservices

To document how to interact with the microservice

To document what the microservice does

To ensure the service work correctly

To ensure we are delivering valuable functionality

Why test our micro-services?

Page 56: BDD-Driven Microservices

To document how to interact with the microservice

To document what the microservice does

To ensure the service work correctly

To ensure we are delivering valuable functionality

Why test our micro-services?

Page 57: BDD-Driven Microservices

To document how to interact with the microservice

To document what the microservice does

To ensure the service work correctly

To ensure we are delivering valuable functionality

Why test our micro-services?

Page 58: BDD-Driven Microservices

To document how to interact with the microservice

To document what the microservice does

To ensure the service work correctly

To ensure we are delivering valuable functionality

Why test our micro-services?

Page 59: BDD-Driven Microservices

To document how to interact with the microservice

To document what the microservice does

To ensure the service work correctly

To ensure we are delivering valuable functionality

Why test our micro-services?

Page 60: BDD-Driven Microservices

To document how to interact with the microservice

To document what the microservice does

To ensure the service work correctly

To ensure we are delivering valuable functionality

Why test our micro-services?

Page 61: BDD-Driven Microservices

“We test our micro-services so we can deploy new features quickly and with confidence”

Page 62: BDD-Driven Microservices

And with aggressive production monitoring

Writing executable specifications and living documentation

To a sufficient level of confidence

Outside-in testing

Pragmatic web service testing

Page 63: BDD-Driven Microservices

And with aggressive production monitoring

Writing executable specifications and living documentation

To a sufficient level of confidence

Outside-in testing

Pragmatic web service testing

Page 64: BDD-Driven Microservices

And with aggressive production monitoring

Writing executable specifications and living documentation

To a sufficient level of confidence

Outside-in testing

Pragmatic web service testing

Page 65: BDD-Driven Microservices

And with aggressive production monitoring

Writing executable specifications and living documentation

To a sufficient level of confidence

Outside-in testing

Pragmatic web service testing

Page 66: BDD-Driven Microservices

And with aggressive production monitoring

Writing executable specifications and living documentation

To a sufficient level of confidence

Outside-in testing

Pragmatic web service testing

Page 67: BDD-Driven Microservices

And with aggressive production monitoring

Writing executable specifications and living documentation

To a sufficient level of confidence

Outside-in testing

Pragmatic web service testing

Page 68: BDD-Driven Microservices

Outside-in development

Page 69: BDD-Driven Microservices

To deliver software that matters

And a common language to build a shared understanding

Using examples at multiple levels

Collaborate to discover requirements and identify uncertainty

The essence of BDD

Page 70: BDD-Driven Microservices

To deliver software that matters

And a common language to build a shared understanding

Using examples at multiple levels

Collaborate to discover requirements and identify uncertainty

The essence of BDD

Page 71: BDD-Driven Microservices

To deliver software that matters

And a common language to build a shared understanding

Using examples at multiple levels

Collaborate to discover requirements and identify uncertainty

The essence of BDD

Page 72: BDD-Driven Microservices

To deliver software that matters

And a common language to build a shared understanding

Using examples at multiple levels

Collaborate to discover requirements and identify uncertainty

The essence of BDD

Page 73: BDD-Driven Microservices

To deliver software that matters

And a common language to build a shared understanding

Using examples at multiple levels

Collaborate to discover requirements and identify uncertainty

The essence of BDD

Page 74: BDD-Driven Microservices

The business owner tells the business

analyst what he wants

12 The business

analyst writes a requirements

document

3 The developer translates the requirements into software

4 The tester translates the requirements

into test cases 5 The technical writer translates

the software into functional and technical

documentationA traditional development process

How does it work?

Page 75: BDD-Driven Microservices

The business owner tells the business

analyst what he wants

12 The business

analyst writes a requirements

document

3 The developer translates the requirements into software

4 The tester translates the requirements

into test cases 5 The technical writer translates

the software into functional and technical

documentationA traditional development process

How does it work?

Page 76: BDD-Driven Microservices

The business owner tells the business

analyst what he wants

12 The business

analyst writes a requirements

document

3 The developer translates the requirements into software

4 The tester translates the requirements

into test cases 5 The technical writer translates

the software into functional and technical

documentationA traditional development process

How does it work?

Page 77: BDD-Driven Microservices

The business owner tells the business

analyst what he wants

12 The business

analyst writes a requirements

document

3 The developer translates the requirements into software

4 The tester translates the requirements

into test cases 5 The technical writer translates

the software into functional and technical

documentationA traditional development process

How does it work?

Page 78: BDD-Driven Microservices

The business owner tells the business

analyst what he wants

12 The business

analyst writes a requirements

document

3 The developer translates the requirements into software

4 The tester translates the requirements

into test cases 5 The technical writer translates

the software into functional and technical

documentationA traditional development process

How does it work?

Page 79: BDD-Driven Microservices

The business owner tells the business

analyst what he wants

12 The business

analyst writes a requirements

document

3 The developer translates the requirements into software

4 The tester translates the requirements

into test cases 5 The technical writer translates

the software into functional and technical

documentationA traditional development process

How does it work?

Page 80: BDD-Driven Microservices

The business owner tells the business

analyst what he wants

12 The business

analyst writes a requirements

document

3 The developer translates the requirements into software

4 The tester translates the requirements

into test cases 5 The technical writer translates

the software into functional and technical

documentationA traditional development process

How does it work?

Page 81: BDD-Driven Microservices

The business owner tells the business

analyst what he wants

12 The business

analyst writes a requirements

document

3 The developer translates the requirements into software

4 The tester translates the requirements

into test cases 5 The technical writer translates

the software into functional and technical

documentationA traditional development process

How does it work?

Page 82: BDD-Driven Microservices

The business owner tells the business

analyst what he wants

12 The business

analyst writes a requirements

document

3 The developer translates the requirements into software

4 The tester translates the requirements

into test cases 5 The technical writer translates

the software into functional and technical

documentationA traditional development process

How does it work?

Page 83: BDD-Driven Microservices

The business owner tells the business

analyst what he wants

12 The business

analyst writes a requirements

document

3 The developer translates the requirements into software

4 The tester translates the requirements

into test cases 5 The technical writer translates

the software into functional and technical

documentationA traditional development process

How does it work?

Page 84: BDD-Driven Microservices

The business owner tells the business

analyst what he wants

12 The business

analyst writes a requirements

document

3 The developer translates the requirements into software

4 The tester translates the requirements

into test cases 5 The technical writer translates

the software into functional and technical

documentationA traditional development process

How does it work?

Page 85: BDD-Driven Microservices

How does it work?

The business owner and the business

analyst have a conversation about

what he needs.

1

2

3

4 The tester uses these scenarios as the basis for

her tests

5

The automated tests provide feedback on progress and help

document the application

The business analyst, the developer and the tester elaborate the

requirements together.

The scenarios guide the developer and act as

automated tests

They define requirements as

structured, English-language format

"scenarios"

A BDD development process

Page 86: BDD-Driven Microservices

How does it work?

The business owner and the business

analyst have a conversation about

what he needs.

1

2

3

4 The tester uses these scenarios as the basis for

her tests

5

The automated tests provide feedback on progress and help

document the application

The business analyst, the developer and the tester elaborate the

requirements together.

The scenarios guide the developer and act as

automated tests

They define requirements as

structured, English-language format

"scenarios"

A BDD development process

Page 87: BDD-Driven Microservices

How does it work?

The business owner and the business

analyst have a conversation about

what he needs.

1

2

3

4 The tester uses these scenarios as the basis for

her tests

5

The automated tests provide feedback on progress and help

document the application

The business analyst, the developer and the tester elaborate the

requirements together.

The scenarios guide the developer and act as

automated tests

They define requirements as

structured, English-language format

"scenarios"

A BDD development process

Page 88: BDD-Driven Microservices

How does it work?

The business owner and the business

analyst have a conversation about

what he needs.

1

2

3

4 The tester uses these scenarios as the basis for

her tests

5

The automated tests provide feedback on progress and help

document the application

The business analyst, the developer and the tester elaborate the

requirements together.

The scenarios guide the developer and act as

automated tests

They define requirements as

structured, English-language format

"scenarios"

A BDD development process

Page 89: BDD-Driven Microservices

How does it work?

The business owner and the business

analyst have a conversation about

what he needs.

1

2

3

4 The tester uses these scenarios as the basis for

her tests

5

The automated tests provide feedback on progress and help

document the application

The business analyst, the developer and the tester elaborate the

requirements together.

The scenarios guide the developer and act as

automated tests

They define requirements as

structured, English-language format

"scenarios"

A BDD development process

Page 90: BDD-Driven Microservices

How does it work?

The business owner and the business

analyst have a conversation about

what he needs.

1

2

3

4 The tester uses these scenarios as the basis for

her tests

5

The automated tests provide feedback on progress and help

document the application

The business analyst, the developer and the tester elaborate the

requirements together.

The scenarios guide the developer and act as

automated tests

They define requirements as

structured, English-language format

"scenarios"

A BDD development process

Page 91: BDD-Driven Microservices

But what about micro-services?

Page 92: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 93: BDD-Driven Microservices

The testing pyramid

Unit Tests

Integration Tests

End-to-end Tests

Page 94: BDD-Driven Microservices

A different testing pyramid

Page 95: BDD-Driven Microservices

A different testing pyramid

Executable Business Specifications

Page 96: BDD-Driven Microservices

A different testing pyramid

Slow-running executable technical specifications

Executable Business Specifications

Page 97: BDD-Driven Microservices

A different testing pyramid

Fast-running executable technical specifications

Slow-running executable technical specifications

Executable Business Specifications

Page 98: BDD-Driven Microservices

Outside-in developmentMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Executable Business specs

Page 99: BDD-Driven Microservices

Outside-in developmentMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Executable Business specs

Scenario: Search movies by director Given the catalog has the following movies: | title | director | actors | | Gladiator | Ridley Scott | Russel Crowe, Joaquin Phoenix | | Letters from Iwo Jima | Clint Eastwood | Ken Watanabe | | Gran Torino | Clint Eastwood | Clint Eastwood, Bee Vang | When I search for movies directed by Clint Eastwood Then I should be presented with the following movies: | title | director | actors | | Letters from Iwo Jima | Clint Eastwood | Ken Watanabe | | Gran Torino | Clint Eastwood | Clint Eastwood, Bee Vang |

Page 100: BDD-Driven Microservices

Outside-in developmentMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Slow-running technical

specs

Page 101: BDD-Driven Microservices

Outside-in developmentMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Slow-running technical

specs

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class) @WebAppConfiguration@IntegrationTest("server.port:0") class WhenFindingMoviesViaTheRestAPI extends Specification { @Autowired MovieRepository movieRepository; @Value('${local.server.port}') int port; def "should list movies by director"() { given: movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO]) when: List<Movie> movies = when().get("/movies/findByDirector/Clint Eastwood").as(List) then: movies.collect {movie -> movie.title} == ["Letters from Iwo Jima", "Gran Torino"] }

Page 102: BDD-Driven Microservices

Outside-in developmentMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Fast-running

technical specs

Page 103: BDD-Driven Microservices

Outside-in developmentMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Fast-running

technical specs

def setup() { repository = Mock(MovieRepository) artistService = new ArtistService(movieRepository: repository) } def "should build actor details from films the artist has acted in and has directed"() { given: "Clint Eastwood has directed some films" repository.findByDirector("Clint Eastwood") >> [LETTERS_FROM_IWO_JIMA, GRAN_TORINO] and: "Clint Eastwood has starred in some films" repository.findByActors("Clint Eastwood") >> [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] when: def artistDetails = artistService.findArtistByName("Clint Eastwood") then: artistDetails.isPresent() and: artistDetails.get().name == "Clint Eastwood" && artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] && artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO] }

Spock

Page 104: BDD-Driven Microservices

Outside-in developmentMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Fast-running

technical specs

Page 105: BDD-Driven Microservices

Outside-in developmentMovie Catalog Service

Resource

Persistance Layer Gateway

Service Layer

Domain model

Repositories

Fast-running

technical specs

class MovieControllerSpecs extends Specification { MovieRepository movieRepository = Mock() def "should find by director regardless of case (#director -> #filteredDirector)"() { given: def controller = new MovieController(repository: movieRepository) when: controller.findByDirector(director) then: 1*movieRepository.findByDirector(filteredDirector) where: director | filteredDirector "Clint Eastwood" | "Clint Eastwood" "Clint eastwood" | "Clint Eastwood" Spock

Page 106: BDD-Driven Microservices

Micro-service Contracts

Page 107: BDD-Driven Microservices

Micro-service ContractsMovie Catalog Service

Resource

Persistance Layer Gateway

Service LayerDomain modelRepositories

Shopping Cart Service

Delivery Service

REST/HTTP

Page 108: BDD-Driven Microservices

Micro-service ContractsMovie Catalog Service

Resource

Persistance Layer Gateway

Service LayerDomain modelRepositories

Shopping Cart Service

REST/HTTP

Delivery Service

Page 109: BDD-Driven Microservices

Micro-service ContractsMovie Catalog Service

Resource

Persistance Layer Gateway

Service LayerDomain modelRepositories

Shopping Cart Service

REST/HTTP

Consumer

Delivery Service

Page 110: BDD-Driven Microservices

Micro-service ContractsMovie Catalog Service

Resource

Persistance Layer Gateway

Service LayerDomain modelRepositories

Shopping Cart Service

REST/HTTP

ConsumerProducer

Delivery Service

Page 111: BDD-Driven Microservices

Micro-service ContractsMovie Catalog Service

Resource

Persistance Layer Gateway

Service LayerDomain modelRepositories

Shopping Cart Service

REST/HTTP

ConsumerProducer

Contract

Delivery Service

Page 112: BDD-Driven Microservices

Micro-service ContractsMovie Catalog Service

Resource

Persistance Layer Gateway

Service LayerDomain modelRepositories

Shopping Cart Service

REST/HTTPContract

Delivery Service

Page 113: BDD-Driven Microservices

Micro-service ContractsMovie Catalog Service

Resource

Persistance Layer Gateway

Service LayerDomain modelRepositories

Shopping Cart Service

Delivery Service

REST/HTTPContract

Mock Shopping

Cart Service

Page 114: BDD-Driven Microservices

Micro-service Contracts

REST/HTTP

Movie Catalog Service

Web app iPhone app Android app

Page 115: BDD-Driven Microservices

Micro-service Contracts

REST/HTTP

Movie Catalog Service

Web app iPhone app Android app

Producer

Page 116: BDD-Driven Microservices

Micro-service Contracts

REST/HTTP

Movie Catalog Service

Web app iPhone app Android app

Consumer

Producer

Page 117: BDD-Driven Microservices

Micro-service Contracts

REST/HTTP

Movie Catalog Service

Web app iPhone app Android app

Consumer

Producer

Consumer

Page 118: BDD-Driven Microservices

Micro-service Contracts

REST/HTTP

Movie Catalog Service

Web app iPhone app Android app

Consumer

Producer

Consumer Consumer

Page 119: BDD-Driven Microservices

Micro-service Contracts

REST/HTTP

Movie Catalog Service

Web app iPhone app Android app

Consumer

Producer

Consumer Consumer

Contract

Page 120: BDD-Driven Microservices

Micro-service Contracts

REST/HTTP

Movie Catalog Service

Web app iPhone app Android app

Consumer

Producer

Consumer Consumer

Contract

Page 121: BDD-Driven Microservices

Micro-service Contracts

REST/HTTP

Movie Catalog Service

Web app iPhone app Android app

Consumer

Producer

Consumer Consumer

Contract

Page 122: BDD-Driven Microservices

Micro-service Contracts

REST/HTTP

Movie Catalog Service

Web app iPhone app Android app

Consumer

Producer

Consumer Consumer

Contract

The Producer API is the sum of the Consumer Contrats

Page 123: BDD-Driven Microservices

Specialised ToolsPublished specificationsAutomated Acceptance Criteria

Verifying the contracts

Page 124: BDD-Driven Microservices

Specialised ToolsPublished specificationsAutomated Acceptance Criteria

Verifying the contracts

Page 125: BDD-Driven Microservices

Specialised ToolsPublished specificationsAutomated Acceptance Criteria

Verifying the contracts

Page 126: BDD-Driven Microservices

Specialised ToolsPublished specificationsAutomated Acceptance Criteria

Verifying the contracts

Page 127: BDD-Driven Microservices

Specialised ToolsPublished specificationsAutomated Acceptance Criteria

Verifying the contracts

Page 128: BDD-Driven Microservices

PactPactoMountebank

More specialised tools

Page 129: BDD-Driven Microservices

PactPactoMountebank

More specialised tools

Page 130: BDD-Driven Microservices

PactPactoMountebank

More specialised tools

Page 131: BDD-Driven Microservices

PactPactoMountebank

More specialised tools

Page 132: BDD-Driven Microservices

PactPactoMountebank

More specialised tools

Page 133: BDD-Driven Microservices

PactPactoMountebank

More specialised tools

Page 134: BDD-Driven Microservices

PactPactoMountebank

More specialised tools

Page 135: BDD-Driven Microservices

Pact and PactoConsumer Driven Contract Testing

42

Consumer Movie Catalog Service

Page 136: BDD-Driven Microservices

Pact and PactoConsumer Driven Contract Testing

42

Consumer Movie Catalog Service

Mock Service

Pact help us create and configure a mock service

Page 137: BDD-Driven Microservices

Pact and PactoConsumer Driven Contract Testing

43

Consumer Movie Catalog Service

Mock Service

Page 138: BDD-Driven Microservices

Pact and PactoConsumer Driven Contract Testing

43

Consumer Movie Catalog Service

Mock Service

We write specifications to describe the expected

behaviour of the service

Page 139: BDD-Driven Microservices

Pact and PactoConsumer Driven Contract Testing

44

Consumer Movie Catalog Service

Mock Service

Page 140: BDD-Driven Microservices

Pact and PactoConsumer Driven Contract Testing

44

Consumer Movie Catalog Service

Mock Service

When we run these specifications, the expected behaviour is recorded in a

‘pact’ file

asdasdasda asdasdasdas asdasdasd asdasdasda

asdasdasdasd asdasdasdasd asdasdasdas

Page 141: BDD-Driven Microservices

Pact and PactoConsumer Driven Contract Testing

45

Consumer Movie Catalog Service

Mock Service

asdasdasda asdasdasdas asdasdasd asdasdasda

asdasdasdasd asdasdasdasd asdasdasdas

Page 142: BDD-Driven Microservices

Pact and PactoConsumer Driven Contract Testing

45

Consumer Movie Catalog Service

Mock Service

We can now use this ‘pact’ to test(drive) the service

implementation

asdasdasda asdasdasdas asdasdasd asdasdasda

asdasdasdasd asdasdasdasd asdasdasdas

Page 143: BDD-Driven Microservices

Levels of confidence

Page 144: BDD-Driven Microservices

From BDD to TDD

“How much automated testing? As much as you need, but no more.”

Page 145: BDD-Driven Microservices

Acceptance testing

Page 146: BDD-Driven Microservices

Acceptance testing

Page 147: BDD-Driven Microservices

Acceptance testing

Page 148: BDD-Driven Microservices

Feature: Adding new movies In order to sell more movies As an online movie seller I want to be able to add movies to the catalog Scenario: Adding movies Given the following movie has just come out | title | director | actors | | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard | When I add this movie to the catalog Then I should be able to find it in the catalog

Page 149: BDD-Driven Microservices

Feature: Adding new movies In order to sell more movies As an online movie seller I want to be able to add movies to the catalog Scenario: Adding movies Given the following movie has just come out | title | director | actors | | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard | When I add this movie to the catalog Then I should be able to find it in the catalog

Page 150: BDD-Driven Microservices

Feature: Adding new movies In order to sell more movies As an online movie seller I want to be able to add movies to the catalog Scenario: Adding movies Given the following movie has just come out | title | director | actors | | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard | When I add this movie to the catalog Then I should be able to find it in the catalog

@When("I add this movie to the catalog") public void addMovieToCatalog() { movieId = rest().given().contentType("application/json") .content(newMovie) .post("/movies") .then().statusCode(200) .and().extract().jsonPath().getString("id");}

Page 151: BDD-Driven Microservices

Feature: Adding new movies In order to sell more movies As an online movie seller I want to be able to add movies to the catalog Scenario: Adding movies Given the following movie has just come out | title | director | actors | | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard | When I add this movie to the catalog Then I should be able to find it in the catalog

Page 152: BDD-Driven Microservices

Feature: Adding new movies In order to sell more movies As an online movie seller I want to be able to add movies to the catalog Scenario: Adding movies Given the following movie has just come out | title | director | actors | | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard | When I add this movie to the catalog Then I should be able to find it in the catalog

Page 153: BDD-Driven Microservices

Feature: Adding new movies In order to sell more movies As an online movie seller I want to be able to add movies to the catalog Scenario: Adding movies Given the following movie has just come out | title | director | actors | | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard | When I add this movie to the catalog Then I should be able to find it in the catalog

@Then("I should be able to find it in the catalog") public void shouldBeAbleToFindMovieInCatalog() { rest().given().contentType("application/json") .get("/movies/{movieId}", movieId) .then().statusCode(200) .and().body("title", equalTo(newMovie.getTitle())) .and().body("director", equalTo(newMovie.getDirector()));}

Page 154: BDD-Driven Microservices

Feature: Adding new movies In order to sell more movies As an online movie seller I want to be able to add movies to the catalog Scenario: Adding movies Given the following movie has just come out | title | director | actors | | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard | When I add this movie to the catalog Then I should be able to find it in the catalog

@Then("I should be able to find it in the catalog") public void shouldBeAbleToFindMovieInCatalog() { rest().given().contentType("application/json") .get("/movies/{movieId}", movieId) .then().statusCode(200) .and().body("title", equalTo(newMovie.getTitle())) .and().body("director", equalTo(newMovie.getDirector()));}

Rest Assured + Serenity

Page 155: BDD-Driven Microservices

Feature: Adding new movies In order to sell more movies As an online movie seller I want to be able to add movies to the catalog Scenario: Adding movies Given the following movie has just come out | title | director | actors | | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard | When I add this movie to the catalog Then I should be able to find it in the catalog

@Then("I should be able to find it in the catalog") public void shouldBeAbleToFindMovieInCatalog() { rest().given().contentType("application/json") .get("/movies/{movieId}", movieId) .then().statusCode(200) .and().body("title", equalTo(newMovie.getTitle())) .and().body("director", equalTo(newMovie.getDirector()));}

Page 156: BDD-Driven Microservices

Testing REST services with Rest-Assured

Page 157: BDD-Driven Microservices

Testing REST services with Rest-Assuredget(“/movies/findByTitle/Gladiator") .then().body("title", equalTo("Gladiator"));

Page 158: BDD-Driven Microservices

Testing REST services with Rest-Assuredget(“/movies/findByTitle/Gladiator") .then().body("title", equalTo("Gladiator"));

Page 159: BDD-Driven Microservices

Testing REST services with Rest-Assured

when().get(“/movies/findByTitle/Gladiator”) .then().body("nominations.category", hasItems("Best Actor", "Special Effects"));

Page 160: BDD-Driven Microservices

Testing REST services with Rest-Assured

when().get(“/movies/findByTitle/Gladiator”) .then().body("nominations.category", hasItems("Best Actor", "Special Effects"));

Page 161: BDD-Driven Microservices

Testing REST services with Rest-Assured

given().contentType("application/json") .content(newMovie) .post("/movies") .then().statusCode(200) .and().extract().jsonPath().getString("id");

Page 162: BDD-Driven Microservices

Testing REST services with Rest-Assured

given().contentType("application/json") .content(newMovie) .post("/movies") .then().statusCode(200) .and().extract().jsonPath().getString("id");

Posting data

Page 163: BDD-Driven Microservices

Testing REST services with Rest-Assured

Movie matchingMovie = get("/movies/findByTitle/Gladiator").as(Movie.class);

Page 164: BDD-Driven Microservices

Testing REST services with Rest-Assured

Movie matchingMovie = get("/movies/findByTitle/Gladiator").as(Movie.class);

Convert responses to Java objects

Page 165: BDD-Driven Microservices

Testing REST services with Rest-Assuredgiven().param("title","Unknown"). when().get("/movies/search"). then().statusCode(404);

Page 166: BDD-Driven Microservices

Testing REST services with Rest-Assuredgiven().param("title","Unknown"). when().get("/movies/search"). then().statusCode(404);

Check for errors

Page 167: BDD-Driven Microservices

Resource-level testing

Page 168: BDD-Driven Microservices

Resource-level testing

Spock

Page 169: BDD-Driven Microservices

Resource-level testing

Spock

Page 170: BDD-Driven Microservices

Resource-level testing

Spock

Page 171: BDD-Driven Microservices

57

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class) @WebAppConfiguration@IntegrationTest("server.port:0") class WhenFindingMovies extends Specification { @Autowired MovieRepository movieRepository; @Value('${local.server.port}') int port; def setup() { movieRepository.deleteAll(); RestAssured.port = port; } def "should list all movies"() { given: movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO]) when: def movies = when().get("/movies").as(List) then: movies.collect {movie -> movie.title} == ["Gladiator", "Letters from Iwo Jima", "Gran Torino"] }

Page 172: BDD-Driven Microservices

57

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class) @WebAppConfiguration@IntegrationTest("server.port:0") class WhenFindingMovies extends Specification { @Autowired MovieRepository movieRepository; @Value('${local.server.port}') int port; def setup() { movieRepository.deleteAll(); RestAssured.port = port; } def "should list all movies"() { given: movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO]) when: def movies = when().get("/movies").as(List) then: movies.collect {movie -> movie.title} == ["Gladiator", "Letters from Iwo Jima", "Gran Torino"] }

Spring Context

Page 173: BDD-Driven Microservices

57

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class) @WebAppConfiguration@IntegrationTest("server.port:0") class WhenFindingMovies extends Specification { @Autowired MovieRepository movieRepository; @Value('${local.server.port}') int port; def setup() { movieRepository.deleteAll(); RestAssured.port = port; } def "should list all movies"() { given: movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO]) when: def movies = when().get("/movies").as(List) then: movies.collect {movie -> movie.title} == ["Gladiator", "Letters from Iwo Jima", "Gran Torino"] }

Spring Integration Tests

Page 174: BDD-Driven Microservices

57

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class) @WebAppConfiguration@IntegrationTest("server.port:0") class WhenFindingMovies extends Specification { @Autowired MovieRepository movieRepository; @Value('${local.server.port}') int port; def setup() { movieRepository.deleteAll(); RestAssured.port = port; } def "should list all movies"() { given: movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO]) when: def movies = when().get("/movies").as(List) then: movies.collect {movie -> movie.title} == ["Gladiator", "Letters from Iwo Jima", "Gran Torino"] }

Rest Assured

Page 175: BDD-Driven Microservices

57

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class) @WebAppConfiguration@IntegrationTest("server.port:0") class WhenFindingMovies extends Specification { @Autowired MovieRepository movieRepository; @Value('${local.server.port}') int port; def setup() { movieRepository.deleteAll(); RestAssured.port = port; } def "should list all movies"() { given: movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, GRAN_TORINO]) when: def movies = when().get("/movies").as(List) then: movies.collect {movie -> movie.title} == ["Gladiator", "Letters from Iwo Jima", "Gran Torino"] }

Page 176: BDD-Driven Microservices

Controller-level testing

Page 177: BDD-Driven Microservices

Controller-level testing

Spock

Page 178: BDD-Driven Microservices

Controller-level testing

Spock

Page 179: BDD-Driven Microservices

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class) @WebAppConfiguration@IntegrationTestclass WhenViewingActorDetailsViaTheController extends Specification { @Autowired ArtistController artistController; def "should retrieve actor details for an artist"() { given: movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]) when: Artist artist = artistController.findArtistDetails("Clint Eastwood") then: artist.name == "Clint Eastwood" and: artist.filmsActedIn.containsAll(THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO) and: artist.filmsDirected.containsAll(LETTERS_FROM_IWO_JIMA, GRAN_TORINO) }

Page 180: BDD-Driven Microservices

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class) @WebAppConfiguration@IntegrationTestclass WhenViewingActorDetailsViaTheController extends Specification { @Autowired ArtistController artistController; def "should retrieve actor details for an artist"() { given: movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]) when: Artist artist = artistController.findArtistDetails("Clint Eastwood") then: artist.name == "Clint Eastwood" and: artist.filmsActedIn.containsAll(THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO) and: artist.filmsDirected.containsAll(LETTERS_FROM_IWO_JIMA, GRAN_TORINO) }

Use a fully wired controller

Page 181: BDD-Driven Microservices

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class) @WebAppConfiguration@IntegrationTestclass WhenViewingActorDetailsViaTheController extends Specification { @Autowired ArtistController artistController; def "should retrieve actor details for an artist"() { given: movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]) when: Artist artist = artistController.findArtistDetails("Clint Eastwood") then: artist.name == "Clint Eastwood" and: artist.filmsActedIn.containsAll(THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO) and: artist.filmsDirected.containsAll(LETTERS_FROM_IWO_JIMA, GRAN_TORINO) } Use domain objects rather than REST calls

Page 182: BDD-Driven Microservices

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MovieServiceApplication.class) @WebAppConfiguration@IntegrationTestclass WhenViewingActorDetailsViaTheController extends Specification { @Autowired ArtistController artistController; def "should retrieve actor details for an artist"() { given: movieCatalogContains([GLADIATOR, LETTERS_FROM_IWO_JIMA, THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO]) when: Artist artist = artistController.findArtistDetails("Clint Eastwood") then: artist.name == "Clint Eastwood" and: artist.filmsActedIn.containsAll(THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO) and: artist.filmsDirected.containsAll(LETTERS_FROM_IWO_JIMA, GRAN_TORINO) }

Page 183: BDD-Driven Microservices

Service or domain-level testing

Page 184: BDD-Driven Microservices

Service or domain-level testing

Spock

Page 185: BDD-Driven Microservices

MovieRepository repositorydef artistServicedef setup() { repository = Mock(MovieRepository) artistService = new ArtistService(movieRepository: repository) } def "should build actor details from films the artist has acted in and has directed"() { given: "Clint Eastwood has directed some films" repository.findByDirector("Clint Eastwood") >> [LETTERS_FROM_IWO_JIMA, GRAN_TORINO] and: "Clint Eastwood has starred in some films" repository.findByActors("Clint Eastwood") >> [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] when: def artistDetails = artistService.findArtistByName("Clint Eastwood") then: artistDetails.isPresent() and: artistDetails.get().name == "Clint Eastwood" && artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] && artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO] }

Page 186: BDD-Driven Microservices

MovieRepository repositorydef artistServicedef setup() { repository = Mock(MovieRepository) artistService = new ArtistService(movieRepository: repository) } def "should build actor details from films the artist has acted in and has directed"() { given: "Clint Eastwood has directed some films" repository.findByDirector("Clint Eastwood") >> [LETTERS_FROM_IWO_JIMA, GRAN_TORINO] and: "Clint Eastwood has starred in some films" repository.findByActors("Clint Eastwood") >> [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] when: def artistDetails = artistService.findArtistByName("Clint Eastwood") then: artistDetails.isPresent() and: artistDetails.get().name == "Clint Eastwood" && artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] && artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO] }

Mocked repositories

Page 187: BDD-Driven Microservices

MovieRepository repositorydef artistServicedef setup() { repository = Mock(MovieRepository) artistService = new ArtistService(movieRepository: repository) } def "should build actor details from films the artist has acted in and has directed"() { given: "Clint Eastwood has directed some films" repository.findByDirector("Clint Eastwood") >> [LETTERS_FROM_IWO_JIMA, GRAN_TORINO] and: "Clint Eastwood has starred in some films" repository.findByActors("Clint Eastwood") >> [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] when: def artistDetails = artistService.findArtistByName("Clint Eastwood") then: artistDetails.isPresent() and: artistDetails.get().name == "Clint Eastwood" && artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] && artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO] }

Call the service

Page 188: BDD-Driven Microservices

MovieRepository repositorydef artistServicedef setup() { repository = Mock(MovieRepository) artistService = new ArtistService(movieRepository: repository) } def "should build actor details from films the artist has acted in and has directed"() { given: "Clint Eastwood has directed some films" repository.findByDirector("Clint Eastwood") >> [LETTERS_FROM_IWO_JIMA, GRAN_TORINO] and: "Clint Eastwood has starred in some films" repository.findByActors("Clint Eastwood") >> [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] when: def artistDetails = artistService.findArtistByName("Clint Eastwood") then: artistDetails.isPresent() and: artistDetails.get().name == "Clint Eastwood" && artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] && artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO] }

Check the outcomes

Page 189: BDD-Driven Microservices

MovieRepository repositorydef artistServicedef setup() { repository = Mock(MovieRepository) artistService = new ArtistService(movieRepository: repository) } def "should build actor details from films the artist has acted in and has directed"() { given: "Clint Eastwood has directed some films" repository.findByDirector("Clint Eastwood") >> [LETTERS_FROM_IWO_JIMA, GRAN_TORINO] and: "Clint Eastwood has starred in some films" repository.findByActors("Clint Eastwood") >> [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] when: def artistDetails = artistService.findArtistByName("Clint Eastwood") then: artistDetails.isPresent() and: artistDetails.get().name == "Clint Eastwood" && artistDetails.get().filmsActedIn == [THE_GOOD_THE_BAD_AND_THE_UGLY, GRAN_TORINO] && artistDetails.get().filmsDirected == [LETTERS_FROM_IWO_JIMA, GRAN_TORINO] }

Page 190: BDD-Driven Microservices

Living Documentation

Page 191: BDD-Driven Microservices

Living Documentation

Page 192: BDD-Driven Microservices

Living Functional Documentation with Serenity and Cucumber

Page 193: BDD-Driven Microservices

65

Scenario: Adding movies Given the following movie has just come out | title | director | actors | | Jurassic World | Colin Trevorrow | Chris Pratt, Bryce Dallas Howard | When I add this movie to the catalog Then I should be able to find it in the catalog

Executable Specifications

Automated tests Living documentation

Page 194: BDD-Driven Microservices

66

Page 195: BDD-Driven Microservices

66

Context

Page 196: BDD-Driven Microservices

66

Context

Narrative

Page 197: BDD-Driven Microservices

67

Page 198: BDD-Driven Microservices

67

Technical details

Page 199: BDD-Driven Microservices

Living API Documentation with Swagger

Springfox

Page 200: BDD-Driven Microservices

69

YAML Specifications Documentation website

Client libraries Test stubs

Page 201: BDD-Driven Microservices

70

@RequestMapping(method = GET) @ApiOperation("List all the movies in the catalog") public List<Movie> findAll() { return repository.findAll();} @RequestMapping(method = POST) @ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST") public Movie add(@RequestBody Movie newMovie) { return repository.save(newMovie);} @RequestMapping(value = "/{id}", method = DELETE) @ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE") public void delete(@PathVariable String id) { repository.delete(id);}

Springfox

Some annotations…

Swagger and Spring Boot

Page 202: BDD-Driven Microservices

70

@RequestMapping(method = GET) @ApiOperation("List all the movies in the catalog") public List<Movie> findAll() { return repository.findAll();} @RequestMapping(method = POST) @ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST") public Movie add(@RequestBody Movie newMovie) { return repository.save(newMovie);} @RequestMapping(value = "/{id}", method = DELETE) @ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE") public void delete(@PathVariable String id) { repository.delete(id);}

Springfox

Some annotations…

Swagger and Spring Boot

Page 203: BDD-Driven Microservices

70

@RequestMapping(method = GET) @ApiOperation("List all the movies in the catalog") public List<Movie> findAll() { return repository.findAll();} @RequestMapping(method = POST) @ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST") public Movie add(@RequestBody Movie newMovie) { return repository.save(newMovie);} @RequestMapping(value = "/{id}", method = DELETE) @ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE") public void delete(@PathVariable String id) { repository.delete(id);}

Springfox

Some annotations…

Swagger and Spring Boot

Page 204: BDD-Driven Microservices

70

@RequestMapping(method = GET) @ApiOperation("List all the movies in the catalog") public List<Movie> findAll() { return repository.findAll();} @RequestMapping(method = POST) @ApiOperation(value = "Add a new movie to the catalog", httpMethod = "POST") public Movie add(@RequestBody Movie newMovie) { return repository.save(newMovie);} @RequestMapping(value = "/{id}", method = DELETE) @ApiOperation(value = "Removing a movie from the catalog", httpMethod = "DELETE") public void delete(@PathVariable String id) { repository.delete(id);}

Springfox

Some annotations…

Swagger and Spring Boot

Page 205: BDD-Driven Microservices

71

Springfox

@EnableAutoConfiguration@EnableSwagger2public class MovieServiceApplication { public static void main(String[] args) { SpringApplication.run(MovieServiceApplication.class, args); } @Bean public Docket moviesApi() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build() .pathMapping("/") .directModelSubstitute(LocalDate.class, String.class) .genericModelSubstitutes(ResponseEntity.class); }} Some configuration…

Swagger and Spring Boot

Page 206: BDD-Driven Microservices

72

Springfox

Documentationbundled with your

web services

Swagger and Spring Boot

Page 207: BDD-Driven Microservices

Production monitoring

Page 208: BDD-Driven Microservices

Automated MonitoringFast provisioningA fast deployment pipeline

So you want to micro-service?

Page 209: BDD-Driven Microservices

Automated health checksReal operationsSmoke tests in production

Simple checks may not be enough

Page 210: BDD-Driven Microservices

An example with Spring Actuator@Componentpublic class CatalogHealth implements HealthIndicator { @Autowired MovieRepository movieRepository; @Override public Health health() { return (isCatalogStocked()) ? Health.status(new Status("UP", "Movie count: " + movieRepository.count())).build() : Health.down().build(); } private boolean isCatalogStocked() { return (movieRepository.count() > 0); }}

Page 211: BDD-Driven Microservices

An example with Spring Actuator@Componentpublic class CatalogHealth implements HealthIndicator { @Autowired MovieRepository movieRepository; @Override public Health health() { return (isCatalogStocked()) ? Health.status(new Status("UP", "Movie count: " + movieRepository.count())).build() : Health.down().build(); } private boolean isCatalogStocked() { return (movieRepository.count() > 0); }}

A Spring Actuator Health Check

Page 212: BDD-Driven Microservices

An example with Spring Actuator@Componentpublic class CatalogHealth implements HealthIndicator { @Autowired MovieRepository movieRepository; @Override public Health health() { return (isCatalogStocked()) ? Health.status(new Status("UP", "Movie count: " + movieRepository.count())).build() : Health.down().build(); } private boolean isCatalogStocked() { return (movieRepository.count() > 0); }}

A Spring Actuator Health Check

Custom logic to decide if the app is working

Page 213: BDD-Driven Microservices

An example with Spring Actuator@Componentpublic class MovieTransactionHealth implements HealthIndicator { @Autowired MovieController movieController; @Override public Health health() { return Health.status(transactionStatus()).build(); } private Status transactionStatus() { try { Movie movie = new Movie("TEST title", "TEST description", "TEST director", ImmutableList.of("TEST actor")); Movie reloadedMovie = movieController.add(movie); movieController.delete(reloadedMovie.getId()); return Status.UP; } catch (Throwable e) { return new Status("DOWN", e.toString()); } }}

Page 214: BDD-Driven Microservices

An example with Spring Actuator@Componentpublic class MovieTransactionHealth implements HealthIndicator { @Autowired MovieController movieController; @Override public Health health() { return Health.status(transactionStatus()).build(); } private Status transactionStatus() { try { Movie movie = new Movie("TEST title", "TEST description", "TEST director", ImmutableList.of("TEST actor")); Movie reloadedMovie = movieController.add(movie); movieController.delete(reloadedMovie.getId()); return Status.UP; } catch (Throwable e) { return new Status("DOWN", e.toString()); } }}

More complex custom logic

Page 215: BDD-Driven Microservices

An example with Spring Actuator

@Componentpublic class MovieTransactionHealth implements HealthIndicator { @Autowired MovieController movieController; @Override public Health health() { return Health.status(transactionStatus()).build(); } private Status transactionStatus() {…} }

@Componentpublic class CatalogHealth implements HealthIndicator { @Autowired MovieRepository movieRepository; @Override public Health health() { return (isCatalogStocked()) ? Health.status(new Status("UP", "Movie count: " + movieRepository.count())).build() : Health.down().build(); } private boolean isCatalogStocked() {…} }

Page 216: BDD-Driven Microservices

Try all this out at home!

Install Gradle

Install MongoDB

Clone the repowakaleo/movie-service

Page 217: BDD-Driven Microservices

Questions?

John Ferguson [email protected]

wakaleohttp://www.wakaleo.com