Documente Academic
Documente Profesional
Documente Cultură
Types of Testing
API Service
Stubs
Microservice Contracts
Service Client
1. Simulates production
2. Real communication
S2 S3
1. Fast feedback
2. No infrastructure setup
Producer Repository
Spring Cloud Contract Verifier
Contract Definition Language (DSL)
• Definition either in groovy or pact format
Used to produce following resources
• JSON stub definitions
Used by client side
Test written by hand, test data provided by Spring
• Server tests
Test generated by Spring
Build script – Consumer (task-webservice)
dependencies
• testCompile("org.springframework.security:spring-security-test")
• testCompile("org.springframework.cloud:spring-cloud-starter-
contract-stub-runner")
Client tests
Create integration test
• Annotations
@RunWith(SpringRunner.class) // 1
@SpringBootTest(webEnvironment = WebEnvironment.MOCK, properties = {
"spring.cloud.discovery.enabled=false",
"spring.cloud.config.enabled=false","stubrunner.idsToServiceIds.basic-comments-webservice-
stubs=comments-webservice" }). // 2
@Import(OAuth2ClientTestConfiguration.class). // 3
@AutoConfigureStubRunner(ids={"anilallewar:basic-comments-webservice-stubs:+:stubs:9083"},
workOffline=true) // 4
@DirtiesContext // 5
Client tests
Actual test
@Test
public void testGetCommentsForTask() {
CommentCollectionResource comments =
this.commentsService.getCommentsForTask(REQUEST_TASK_ID);
Assert.assertEquals(2, comments.getTaskComments().size());
Assert.assertTrue(comments.getTaskComments().get(0).getTaskId().equals(TEST_TASK_ID));
}
dependencies
• testCompile('org.springframework.cloud:spring-cloud-starter-
contract-verifier')
Build script – Producer (comments-webservice)
// Setup the package which contains base classes that the spring cloud contract test case would extend
contracts {
packageWithBaseClasses = 'com.anilallewar.microservices.comments.contracts'
}
clean.doFirst {
delete "~/.m2/repository/anilallewar/basic-comments-webservice"
delete "~/.m2/repository/anilallewar/basic-comments-webservice-stubs"
}
// Setup the artifact id with which the stubs jar would be published, the group id comes from the 'group' attribute defined earlier
publishing {
publications {
mavenJava(MavenPublication) {
artifactId jar.baseName
version jar.version
from components.java
}
stubs(MavenPublication) {
artifactId "${jar.baseName}-stubs"
version jar.version
artifact verifierStubsJar
}
}
}
Contract DSL
Src/test/resources/contracts
response {
request { status 200
method 'GET' body( [
url $(consumer(regex('/comments/([0-9a- [
zA-z]+)')), producer('/comments/task11')) "taskId": "task11",
headers { "comment": "comment on task11",
accept(applicationJson()) "posted": $(consumer('2015-04-
} 23'),producer(execute('convertTimeValueToDate($it)')))
} ]]
)
headers {
contentType('application/json')
}
}
Abstract Base Class
Generated test extends the defined base class
Since the package for base classes is defined
as com.anilallewar.microservices.comments.contracts and
the contract is defined under the task/comments folder
under test/resources/contracts, the base class name is
TaskCommentsBase
Add @Ignore annotation – not a test class
Abstract base class
Inject a WebApplicationContext so that Spring dependency is
initialized correctly.
Annotations
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { CommentsApplication.class }, webEnvironment
= WebEnvironment.MOCK, properties = {
"spring.cloud.discovery.enabled=false", "spring.cloud.config.enabled=false"
})
Run tests
Run the test with ./gradlew clean build
• This will generate the server tests under /comments-
webservice/build/generated-test-
sources/contracts/org/springframework/cloud/contract/verifier
/tests
Publish the contract stub using ./gradlew
publishToMavenLocal
Once the contract is published, go to the task-webservice
folder and run ./gradlew clean build
• This time around the test should pass
Distributed Tracing
Sleuth & Zipkin
Sleuth
• Attaches unique id to request as it passes through enabled services
• Logs can be mined using aggregation tools like ELK (ElasticSearch,
Logstash and Kibana)
Zipkin
• Distributed tracing system
• Gathers timing data across Microservices – collection and lookup
Dependencies
Create a new project by visiting https://start.spring.io/
• Gradle project –> with Java and Spring Boot 1.5.4
• Group -> com.<name>.microservices
• Artifact -> tracing
• Dependencies -> Zipkin UI, Zipkin Client
Additional dependency
• compile('io.zipkin.java:zipkin-server')
Run ./gradlew clean build eclipse
Code changes
Application.properties
• server.port=9411
Alternatively you can add configuration on the centralized
configuration server
Add @EnableZipkinServer annotation on the Spring boot
application class
Add Zipkin client properties
Check below properties exists in configuration files for “api-
gateway”, “comments-webservice”, “task-webservice” and
“user-webservice”
spring:
zipkin:
baseUrl: http://localhost:9411/
sleuth:
sampler:
percentage: 1.0
sample:
zipkin:
enabled: true
View Traces
Run all the Microservices and other servers (zipkin server,
web-portal etc)
Hit http://localhost:9411/ (Zipkin base url)
UI
• Find specific trace and timing information
• Service dependency graph
Trace id is added to logs – enables distributed log analysis
Sample Trace
Contact Me
anilallewar@yahoo.co.in
https://www.linkedin.com/in/anilallewar
https://github.com/anilallewar
http://www.slideshare.net/anilallewar
@anilallewar