SlideShare a Scribd company logo
Integration testing with Docker Compose and JUnit
Dariusz Lorenc
Boris Kravtsov
Pivotal Labs
Problem
End-2-end test of GemFire in various cluster configurations
and with different failover scenarios
GemFire
GemFire is a distributed, in-memory database with strong data
consistency, built to support transactional applications with low latency
and high concurrency needs
GemFire Server
GemFire
GemFire Server GemFire Server
Partitioned
Data
Partitioned
Data
Partitioned
Data
GemFire ServerGemFire Server GemFire Server
Partitioned
Data
Partitioned
Data
Partitioned
Data
Client
WAN / Multi-Site
Gateway Hub
Gateway Hub
Relational Database
Docker Compose to the rescue
Docker Compose is a tool for defining and running multi-container
Docker applications
Docker Compose JUnit Rule
A JUnit rule to manage docker containers using docker-compose
• Start and stop docker-compose multi-container applications
• Waits for services to become available before running tests
• Extends logging and debugging
https://github.com/palantir/docker-compose-rule
GreetingCounter
Master
Our Sample Distributed System
Test First - Happy Path
@Test

public void shouldReturnData(){

get("/info")

.then().assertThat()

.body("counter", isA(Number.class))

.body("greeting", is("Hello World"));

}
Spring Boot - Application.kt
@SpringBootApplication
open class Application {
companion object {
@JvmStatic fun main(args: Array<String>) {
SpringApplication.run(Application::class.java,
*args)
}
}
}
Greeting Service
@RestController

class Controller {



@RequestMapping("/greeting")

fun greet(): Greeting {

return Greeting("Hello World")

}

}
data class Greeting(val greeting: String)
Counter Service
@RestController

class Controller {



val counter = AtomicLong()



@RequestMapping("/counter")

fun count(): Counter {

return Counter(counter.incrementAndGet())

}

}
data class Counter(val counter: Long)
Master Service
@RestController

class Controller @Autowired constructor(
val greetingClient: GreetingClient,

val counterClient: CounterClient) {



@RequestMapping("/info")

fun info(): Response {

return Response(counterClient.counter().counter,

greetingClient.greeting().greeting)

}

}
data class Response(val counter: Long, val greeting: String)
Master Service - Greeting Client
@FeignClient(name = "greeting",
url = "http://greeting-service:8080")

interface GreetingClient {


@RequestMapping(value = "/greeting",
method = arrayOf(RequestMethod.GET))

fun greeting(): Greeting

}
Master Service - Counter Client
@FeignClient(name = "counter",
url = "http://counter-service:8080")

interface CounterClient {


@RequestMapping(value = “/counter”,
method = arrayOf(RequestMethod.GET))

fun counter(): Counter

}
GreetingCounter
Master
Next Step: Dockerize Our Services
Dockerfiles
FROM frolvlad/alpine-oraclejdk8:slim
ADD master-service-1.0.0.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
Base image
Add the app’s fat jar
Expose the port
Start the java app
Build Docker Image with Gradle (Transmodo plugin)
buildscript {
dependencies {
classpath('se.transmode.gradle:gradle-docker:1.2')
}
}
group = '<your docker group name>'
apply plugin: 'docker'
task buildDocker(type: Docker, dependsOn: build) {
push = true
applicationName = jar.baseName
dockerfile = file('src/main/docker/Dockerfile')
doFirst {
copy {
from jar
into stageDir
}
}
}
Gradle Docker plugin
Your Docker Hub ID
Build Docker task
GreetingCounter
Master
GreetingCount
“Docker Composed” Services
Docker Compose
docker-compose.yml
Greeting
Counter
Master
greeting-service:
image: lorenc/greeting-service
ports:
- “8081:8080"
counter-service:
image: lorenc/counter-service
ports:
- "8082:8080"
master-service:
image: lorenc/master-service
ports:
- "8083:8080"
links:
- greeting-service
- counter-service
Integration Test Setup
@Rule

public DockerComposeRule docker = DockerComposeRule.builder()

.file("../docker-compose.yml")

.build();
@Before

public void setUp() throws Exception {

docker.dockerCompose().up();

}



@After

public void tearDown() throws Exception {

docker.dockerCompose().down();

}
Health Checks & Logs
@Rule

public DockerComposeRule docker = DockerComposeRule.builder()

.file("../docker-compose.yml")

.waitingForService("greeting-service",
toRespondOverHttp(8080, TO_EXTERNAL_URI))

.waitingForService("counter-service",
toRespondOverHttp(8080, TO_EXTERNAL_URI))

.waitingForService("master-service",
toRespondOverHttp(8080, TO_EXTERNAL_URI))

.saveLogsTo("build/docker-logs")

.build();
Automated integration testing of distributed systems with Docker Compose and JUnit
What could possibly go wrong?
@Test

public void shouldReturnHolaWhenGreetingServiceDown(){

docker.dockerCompose().container("greeting-service").stop();



get("/info")

.then().assertThat()

.body("greeting", is("Hola!"));

}
What could possibly go wrong?
@Test

public void shouldReturn42WhenCounterServiceDown() {

docker.dockerCompose().container("counter-service").stop();



get("/info")

.then().assertThat()

.body("counter", is(42));

}
@FeignClient(name = "greeting",
url = "http://greeting-service:8080",
fallback = DefaultGreeting::class)

interface GreetingClient {


@RequestMapping(value = "/greeting",
method = arrayOf(RequestMethod.GET))

fun greeting(): Greeting

}
@Component

class DefaultGreeting : GreetingClient {

override fun greeting(): Greeting {

return Greeting("Hola!")

}

}
Master Service - Greeting Client
Master Service - Counter Client
@FeignClient(name = "counter",
url = "http://counter-service:8080",
fallback = DefaultCounter::class)

interface CounterClient {


@RequestMapping(value = “/counter”,
method = arrayOf(RequestMethod.GET))

fun counter(): Counter

}
@Component

class DefaultCounter : CounterClient {

override fun counter(): Counter {

return Counter(42)

}

}
Demo
References
https://github.com/d-lorenc/junit-docker-demo
https://github.com/palantir/docker-compose-rule
Automated integration testing of distributed systems with Docker Compose and JUnit

More Related Content

What's hot (20)

PDF
Sharing is Caring: Toward Creating Self-tuning Multi-tenant Kafka (Anna Povzn...
HostedbyConfluent
 
PPTX
Microservices with Node and Docker
Tony Pujals
 
PPTX
Application Deployment and Management at Scale at 1&1
Matt Baldwin
 
PDF
GWT Enterprise Edition
Gilad Garon
 
PDF
[OpenInfra Days Korea 2018] Day 2 - E4 - 핸즈온 워크샵: 서버리스가 컨테이너를 만났을 때
OpenStack Korea Community
 
PDF
Running Projects in Application Containers, System Containers & VMs - Jelasti...
Jelastic Multi-Cloud PaaS
 
PPTX
Building WebLogic Domains With WLST
C2B2 Consulting
 
PDF
Deploying Flink on Kubernetes - David Anderson
Ververica
 
PDF
Oops! I started a broker | Yinon Kahta, Taboola
HostedbyConfluent
 
PPTX
Deploying a secured Flink cluster on Kubernetes
Edward Alexander Rojas Clavijo
 
PDF
How Apache Kafka® Works
confluent
 
PDF
Cloud Foundry for Spring Developers
Gunnar Hillert
 
PDF
Optimizing {Java} Application Performance on Kubernetes
Dinakar Guniguntala
 
PPTX
JavaEdge 2008: Your next version control system
Gilad Garon
 
PPTX
Migration of an Enterprise UI Microservice System from Cloud Foundry to Kuber...
Tony Erwin
 
PDF
Camunda and Apache Cassandra
camunda services GmbH
 
PPTX
ElasticKube, a Container Management Platform for Kubernetes
Matt Baldwin
 
PDF
Kubernetes deployment strategies - CNCF Webinar
Etienne Tremel
 
PDF
Deep Dive into Kubernetes - Part 1
Imesh Gunaratne
 
PDF
Kubernetes - A Comprehensive Overview
Bob Killen
 
Sharing is Caring: Toward Creating Self-tuning Multi-tenant Kafka (Anna Povzn...
HostedbyConfluent
 
Microservices with Node and Docker
Tony Pujals
 
Application Deployment and Management at Scale at 1&1
Matt Baldwin
 
GWT Enterprise Edition
Gilad Garon
 
[OpenInfra Days Korea 2018] Day 2 - E4 - 핸즈온 워크샵: 서버리스가 컨테이너를 만났을 때
OpenStack Korea Community
 
Running Projects in Application Containers, System Containers & VMs - Jelasti...
Jelastic Multi-Cloud PaaS
 
Building WebLogic Domains With WLST
C2B2 Consulting
 
Deploying Flink on Kubernetes - David Anderson
Ververica
 
Oops! I started a broker | Yinon Kahta, Taboola
HostedbyConfluent
 
Deploying a secured Flink cluster on Kubernetes
Edward Alexander Rojas Clavijo
 
How Apache Kafka® Works
confluent
 
Cloud Foundry for Spring Developers
Gunnar Hillert
 
Optimizing {Java} Application Performance on Kubernetes
Dinakar Guniguntala
 
JavaEdge 2008: Your next version control system
Gilad Garon
 
Migration of an Enterprise UI Microservice System from Cloud Foundry to Kuber...
Tony Erwin
 
Camunda and Apache Cassandra
camunda services GmbH
 
ElasticKube, a Container Management Platform for Kubernetes
Matt Baldwin
 
Kubernetes deployment strategies - CNCF Webinar
Etienne Tremel
 
Deep Dive into Kubernetes - Part 1
Imesh Gunaratne
 
Kubernetes - A Comprehensive Overview
Bob Killen
 

Viewers also liked (14)

PDF
Integration Testing with Docker Containers with DockerCompose
Mike Holdsworth
 
PDF
Efficient Parallel Testing with Docker
Laura Frank Tacho
 
PDF
Docker for (Java) Developers
Rafael Benevides
 
PDF
信息系统架构设计
Weijun Zhong
 
PDF
不断归零的前端人生 - 2016 中国软件开发者大会
Joseph Chiang
 
PDF
淺談 Geb 網站自動化測試(JCConf 2014)
Kyle Lin
 
PDF
Spring IO 2016 - Spring Cloud Microservices, a journey inside a financial entity
Toni Jara
 
PPTX
需求分析及相关技术
Weijun Zhong
 
PDF
Docker初识
hubugui
 
PDF
Efficient Parallel Testing with Docker by Laura Frank
Docker, Inc.
 
PDF
Microservices Workshop All Topics Deck 2016
Adrian Cockcroft
 
PDF
Agile Transformation and Cultural Change
Johnny Ordóñez
 
PPTX
The hardest part of microservices: your data
Christian Posta
 
PPTX
Testing web services
Taras Lytvyn
 
Integration Testing with Docker Containers with DockerCompose
Mike Holdsworth
 
Efficient Parallel Testing with Docker
Laura Frank Tacho
 
Docker for (Java) Developers
Rafael Benevides
 
信息系统架构设计
Weijun Zhong
 
不断归零的前端人生 - 2016 中国软件开发者大会
Joseph Chiang
 
淺談 Geb 網站自動化測試(JCConf 2014)
Kyle Lin
 
Spring IO 2016 - Spring Cloud Microservices, a journey inside a financial entity
Toni Jara
 
需求分析及相关技术
Weijun Zhong
 
Docker初识
hubugui
 
Efficient Parallel Testing with Docker by Laura Frank
Docker, Inc.
 
Microservices Workshop All Topics Deck 2016
Adrian Cockcroft
 
Agile Transformation and Cultural Change
Johnny Ordóñez
 
The hardest part of microservices: your data
Christian Posta
 
Testing web services
Taras Lytvyn
 
Ad

Similar to Automated integration testing of distributed systems with Docker Compose and JUnit (20)

PDF
Infrastructure = code - 1 year later
Christian Ortner
 
PDF
Deploying configurable frontend web application containers
José Moreira
 
PPTX
Nats meetup oct 2016 docker 112
Nirmal Mehta
 
PPTX
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
Patrick Chanezon
 
PDF
Clojure and the Web
nickmbailey
 
PDF
Configuration Management and Transforming Legacy Applications in the Enterpri...
Docker, Inc.
 
PDF
Container orchestration from theory to practice
Docker, Inc.
 
PDF
Integration tests: use the containers, Luke!
Roberto Franchini
 
PDF
In the Brain of Hans Dockter: Gradle
Skills Matter
 
PPTX
Docker for developers z java
andrzejsydor
 
PDF
Excelian hyperledger walkthrough-feb17
Excelian | Luxoft Financial Services
 
PPTX
Taking Jenkins Pipeline to the Extreme
yinonavraham
 
PPTX
Docker Enterprise Workshop - Technical
Patrick Chanezon
 
PDF
Cannibalising The Google App Engine
catherinewall
 
PDF
Running Django on Docker: a workflow and code
Danielle Madeley
 
PPTX
Docker Networking - Common Issues and Troubleshooting Techniques
Sreenivas Makam
 
PDF
Practical Design Patterns in Docker Networking
Docker, Inc.
 
PDF
Containerised Testing at Demonware : PyCon Ireland 2016
Thomas Shaw
 
PDF
Building Web Scale Apps with Docker and Mesos by Alex Rukletsov (Mesosphere)
Docker, Inc.
 
PPTX
Real World Lessons on the Pain Points of Node.JS Application
Ben Hall
 
Infrastructure = code - 1 year later
Christian Ortner
 
Deploying configurable frontend web application containers
José Moreira
 
Nats meetup oct 2016 docker 112
Nirmal Mehta
 
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
Patrick Chanezon
 
Clojure and the Web
nickmbailey
 
Configuration Management and Transforming Legacy Applications in the Enterpri...
Docker, Inc.
 
Container orchestration from theory to practice
Docker, Inc.
 
Integration tests: use the containers, Luke!
Roberto Franchini
 
In the Brain of Hans Dockter: Gradle
Skills Matter
 
Docker for developers z java
andrzejsydor
 
Excelian hyperledger walkthrough-feb17
Excelian | Luxoft Financial Services
 
Taking Jenkins Pipeline to the Extreme
yinonavraham
 
Docker Enterprise Workshop - Technical
Patrick Chanezon
 
Cannibalising The Google App Engine
catherinewall
 
Running Django on Docker: a workflow and code
Danielle Madeley
 
Docker Networking - Common Issues and Troubleshooting Techniques
Sreenivas Makam
 
Practical Design Patterns in Docker Networking
Docker, Inc.
 
Containerised Testing at Demonware : PyCon Ireland 2016
Thomas Shaw
 
Building Web Scale Apps with Docker and Mesos by Alex Rukletsov (Mesosphere)
Docker, Inc.
 
Real World Lessons on the Pain Points of Node.JS Application
Ben Hall
 
Ad

Recently uploaded (20)

PDF
🚀 Let’s Build Our First Slack Workflow! 🔧.pdf
SanjeetMishra29
 
PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PPTX
Agentforce World Tour Toronto '25 - MCP with MuleSoft
Alexandra N. Martinez
 
PDF
UPDF - AI PDF Editor & Converter Key Features
DealFuel
 
PDF
Peak of Data & AI Encore AI-Enhanced Workflows for the Real World
Safe Software
 
PDF
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
PDF
Future-Proof or Fall Behind? 10 Tech Trends You Can’t Afford to Ignore in 2025
DIGITALCONFEX
 
PDF
How do you fast track Agentic automation use cases discovery?
DianaGray10
 
PDF
“Squinting Vision Pipelines: Detecting and Correcting Errors in Vision Models...
Edge AI and Vision Alliance
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PPTX
Designing_the_Future_AI_Driven_Product_Experiences_Across_Devices.pptx
presentifyai
 
PPTX
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
PPTX
From Sci-Fi to Reality: Exploring AI Evolution
Svetlana Meissner
 
PPTX
Agentforce World Tour Toronto '25 - Supercharge MuleSoft Development with Mod...
Alexandra N. Martinez
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
“NPU IP Hardware Shaped Through Software and Use-case Analysis,” a Presentati...
Edge AI and Vision Alliance
 
PDF
NASA A Researcher’s Guide to International Space Station : Physical Sciences ...
Dr. PANKAJ DHUSSA
 
PPTX
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
🚀 Let’s Build Our First Slack Workflow! 🔧.pdf
SanjeetMishra29
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
Agentforce World Tour Toronto '25 - MCP with MuleSoft
Alexandra N. Martinez
 
UPDF - AI PDF Editor & Converter Key Features
DealFuel
 
Peak of Data & AI Encore AI-Enhanced Workflows for the Real World
Safe Software
 
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
Future-Proof or Fall Behind? 10 Tech Trends You Can’t Afford to Ignore in 2025
DIGITALCONFEX
 
How do you fast track Agentic automation use cases discovery?
DianaGray10
 
“Squinting Vision Pipelines: Detecting and Correcting Errors in Vision Models...
Edge AI and Vision Alliance
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
Designing_the_Future_AI_Driven_Product_Experiences_Across_Devices.pptx
presentifyai
 
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
From Sci-Fi to Reality: Exploring AI Evolution
Svetlana Meissner
 
Agentforce World Tour Toronto '25 - Supercharge MuleSoft Development with Mod...
Alexandra N. Martinez
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
“NPU IP Hardware Shaped Through Software and Use-case Analysis,” a Presentati...
Edge AI and Vision Alliance
 
NASA A Researcher’s Guide to International Space Station : Physical Sciences ...
Dr. PANKAJ DHUSSA
 
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 

Automated integration testing of distributed systems with Docker Compose and JUnit

  • 1. Integration testing with Docker Compose and JUnit Dariusz Lorenc Boris Kravtsov
  • 3. Problem End-2-end test of GemFire in various cluster configurations and with different failover scenarios
  • 4. GemFire GemFire is a distributed, in-memory database with strong data consistency, built to support transactional applications with low latency and high concurrency needs
  • 5. GemFire Server GemFire GemFire Server GemFire Server Partitioned Data Partitioned Data Partitioned Data GemFire ServerGemFire Server GemFire Server Partitioned Data Partitioned Data Partitioned Data Client WAN / Multi-Site Gateway Hub Gateway Hub Relational Database
  • 6. Docker Compose to the rescue Docker Compose is a tool for defining and running multi-container Docker applications
  • 7. Docker Compose JUnit Rule A JUnit rule to manage docker containers using docker-compose • Start and stop docker-compose multi-container applications • Waits for services to become available before running tests • Extends logging and debugging https://github.com/palantir/docker-compose-rule
  • 9. Test First - Happy Path @Test
 public void shouldReturnData(){
 get("/info")
 .then().assertThat()
 .body("counter", isA(Number.class))
 .body("greeting", is("Hello World"));
 }
  • 10. Spring Boot - Application.kt @SpringBootApplication open class Application { companion object { @JvmStatic fun main(args: Array<String>) { SpringApplication.run(Application::class.java, *args) } } }
  • 11. Greeting Service @RestController
 class Controller {
 
 @RequestMapping("/greeting")
 fun greet(): Greeting {
 return Greeting("Hello World")
 }
 } data class Greeting(val greeting: String)
  • 12. Counter Service @RestController
 class Controller {
 
 val counter = AtomicLong()
 
 @RequestMapping("/counter")
 fun count(): Counter {
 return Counter(counter.incrementAndGet())
 }
 } data class Counter(val counter: Long)
  • 13. Master Service @RestController
 class Controller @Autowired constructor( val greetingClient: GreetingClient,
 val counterClient: CounterClient) {
 
 @RequestMapping("/info")
 fun info(): Response {
 return Response(counterClient.counter().counter,
 greetingClient.greeting().greeting)
 }
 } data class Response(val counter: Long, val greeting: String)
  • 14. Master Service - Greeting Client @FeignClient(name = "greeting", url = "http://greeting-service:8080")
 interface GreetingClient { 
 @RequestMapping(value = "/greeting", method = arrayOf(RequestMethod.GET))
 fun greeting(): Greeting
 }
  • 15. Master Service - Counter Client @FeignClient(name = "counter", url = "http://counter-service:8080")
 interface CounterClient { 
 @RequestMapping(value = “/counter”, method = arrayOf(RequestMethod.GET))
 fun counter(): Counter
 }
  • 17. Dockerfiles FROM frolvlad/alpine-oraclejdk8:slim ADD master-service-1.0.0.jar app.jar EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"] Base image Add the app’s fat jar Expose the port Start the java app
  • 18. Build Docker Image with Gradle (Transmodo plugin) buildscript { dependencies { classpath('se.transmode.gradle:gradle-docker:1.2') } } group = '<your docker group name>' apply plugin: 'docker' task buildDocker(type: Docker, dependsOn: build) { push = true applicationName = jar.baseName dockerfile = file('src/main/docker/Dockerfile') doFirst { copy { from jar into stageDir } } } Gradle Docker plugin Your Docker Hub ID Build Docker task
  • 20. docker-compose.yml Greeting Counter Master greeting-service: image: lorenc/greeting-service ports: - “8081:8080" counter-service: image: lorenc/counter-service ports: - "8082:8080" master-service: image: lorenc/master-service ports: - "8083:8080" links: - greeting-service - counter-service
  • 21. Integration Test Setup @Rule
 public DockerComposeRule docker = DockerComposeRule.builder()
 .file("../docker-compose.yml")
 .build(); @Before
 public void setUp() throws Exception {
 docker.dockerCompose().up();
 }
 
 @After
 public void tearDown() throws Exception {
 docker.dockerCompose().down();
 }
  • 22. Health Checks & Logs @Rule
 public DockerComposeRule docker = DockerComposeRule.builder()
 .file("../docker-compose.yml")
 .waitingForService("greeting-service", toRespondOverHttp(8080, TO_EXTERNAL_URI))
 .waitingForService("counter-service", toRespondOverHttp(8080, TO_EXTERNAL_URI))
 .waitingForService("master-service", toRespondOverHttp(8080, TO_EXTERNAL_URI))
 .saveLogsTo("build/docker-logs")
 .build();
  • 24. What could possibly go wrong? @Test
 public void shouldReturnHolaWhenGreetingServiceDown(){
 docker.dockerCompose().container("greeting-service").stop();
 
 get("/info")
 .then().assertThat()
 .body("greeting", is("Hola!"));
 }
  • 25. What could possibly go wrong? @Test
 public void shouldReturn42WhenCounterServiceDown() {
 docker.dockerCompose().container("counter-service").stop();
 
 get("/info")
 .then().assertThat()
 .body("counter", is(42));
 }
  • 26. @FeignClient(name = "greeting", url = "http://greeting-service:8080", fallback = DefaultGreeting::class)
 interface GreetingClient { 
 @RequestMapping(value = "/greeting", method = arrayOf(RequestMethod.GET))
 fun greeting(): Greeting
 } @Component
 class DefaultGreeting : GreetingClient {
 override fun greeting(): Greeting {
 return Greeting("Hola!")
 }
 } Master Service - Greeting Client
  • 27. Master Service - Counter Client @FeignClient(name = "counter", url = "http://counter-service:8080", fallback = DefaultCounter::class)
 interface CounterClient { 
 @RequestMapping(value = “/counter”, method = arrayOf(RequestMethod.GET))
 fun counter(): Counter
 } @Component
 class DefaultCounter : CounterClient {
 override fun counter(): Counter {
 return Counter(42)
 }
 }
  • 28. Demo