Spring Cloud Sleuth 3.0.0 released
With the release of the Spring Cloud 2020.0.0 (aka Ilford) release train we’re more than happy to announce the general availability of Spring Cloud Sleuth 3.0.0. In this blog post I’ll describe the most notable released features (in order of their release dates).
Removes Deprecated Modules
Removes ribbon, zuul, hystrix and Spring Cloud Aws support. Check this PR for more information.
Removes Zipkin Dependencies from Core
Zipkin is no longer a part of core of Sleuth. You can check out more in this PR.
Added MANUAL Reactor Instrumentation
Up till now we’ve been supporting ON_EACH
and ON_LAST
Reactor instrumentation modes. That means that we would wrap every single Reactor operator (ON_EACH
) or the last operator (ON_LAST
). Those wrappings would do their best to put trace related entries in such a way that thread local based instrumentations would work out of the box (e.g. the MDC context, Tracer.currentSpan()
etc.). The problem was that on each wrapping downgraded performance drastically and worked most of the time. The on last operator wrapping downgraded performance a lot and worked sometimes. Both had their issues when flatMap
operators were called and thread switching took place.
With this commit we’ve introduced the manual way of instrumenting Reactor. We came to the conclusion that the thread local based paradigm doesn’t work well with Reactor. We can’t guess for the user what they really want to achieve and which operators should be wrapped. That’s why with the MANUAL
instrumentation mode you can use the WebFluxSleuthOperators
or MessagingSleuthOperators
to provide a lambda that should have the tracing context set in thread local.
MANUAL Reactor Instrumentation Default in Spring Cloud Gateway
With this issue we’re setting the manual instrumentation as the default one for Spring Cloud Gateway. The performance gets drastically improved and the tracing context still gets automatically propagated. If you need to do some customized logging etc. just use the WebFluxSleuthOperators
.
Remove The Legacy MDC Entries
This issue introduces a change in the MDC keys (no more X-B3-...
entries in MDC).
Before
2019-06-27 19:36:11,774 INFO {X-B3-SpanId=e30b6a75bcff782b, X-B3-TraceId=e30b6a75bcff782b, X-Span-Export=false, spanExportable=false, spanId=e30b6a75bcff782b, traceId=e30b6a75bcff782b} some log!
After
2019-06-27 19:36:11,774 INFO {spanId=e30b6a75bcff782b, traceId=e30b6a75bcff782b} some log!
Code Refactoring
Removing Zipkin Starter
The spring-cloud-starter-zipkin
dependency is removed. You need to add spring-cloud-starter-sleuth
and the spring-cloud-sleuth-zipkin
dependency.
New Tracer Abstraction
OpenZipkin Brave was there in Sleuth’s code as the main abstraction since Sleuth 2.0.0. We’ve decided that with Sleuth 3.0.0 we can create our own abstraction (as we do in each Spring Cloud project) so that OpenZipkin Brave becomes one of the supported tracer implementations.
With this PR we’ve introduced a new abstraction that wraps Brave. We also added support for another tracer - OpenTelemetry.
Aligning with Spring Boot
With this PR and that PR we’ve refactored Spring Cloud Sleuth to reflect Spring Boot’s module setup. We’ve split the project into API, instrumentations, auto-configurations etc. Also the documentation layout was updated to look in the same way the Spring Boot one does.
OpenTelemetry support
Initially, with this commit, we’ve added a spring-cloud-sleuth-otel
module inside Spring Cloud Sleuth that introduced OpenTelemetry support.
With this PR we’ve decided to move Spring Cloud Sleuth and OpenTelemetry integration to an incubator project. Once OpenTelemetry & OpenTelemetry Instrumentation projects become stable we will consider next steps.
Links
- Spring Cloud Sleuth 3.0.0 docs
- Spring Cloud Sleuth OpenTelemetry project
- Spring Cloud Sleuth OpenTelemetry docs
- Spring Cloud Sleuth 3.0.0 release notes
- Spring Cloud Sleuth 3.0.0 migration guide
Stay in touch!
In case of any questions don’t hesitate to ping us
- On Github
- On Gitter
- On Stackoverflow
Spring Cloud Contract 3.0.0 released
With the release of the Spring Cloud 2020.0.0 (aka Ilford) release train we’re more than happy to announce the general availability of Spring Cloud Contract 3.0.0. In this blog post I’ll describe the most notable released features (in order of their release dates).
Incremental Test Generation for Maven
With the Incremental Test Generation for Maven we’re generating tests, stubs and stubs jar only if the contracts have changed. The feature is opt-out (enabled by default).
Resolves Credentials from settings.xml
With the
support to resolve credentials from settings.xml when using Aether based solution to fetch the contracts / stubs, we will reuse your settings.xml
credentials for the given server id (via the stubrunner.server-id
property).
Rewrite Groovy to Java
It was fantastic to see so many people take part in rewriting the Spring Cloud Contract’s codebase from Groovy to Java. You can check this issue for more information.
Allow to Extend Contract & Stubs
With this issue and this pull request we’ve added an option to provide metadata
to your contracts. Since we didn’t want to map all WireMock properties to the core of our Contract definition, we’ve allowed passing of metadata under the wiremock
key. The passed value can be an actual WireMock definition. We will map that part to the generated stub.
Example of adding delays:
Contract.make {
request {
method GET()
url '/drunks'
}
response {
status OK()
body([
count: 100
])
headers {
contentType("application/json")
}
}
metadata([wiremock: '''\
{
"response" : {
"delayDistribution": {
"type": "lognormal",
"median": 80,
"sigma": 0.4
}
}
}
'''
])
That also means that you can provide your own metadata. You can read more about this in the documentation
- existing metadata entries
- customization of WireMock via metadata
- customization of WireMock via metadata & custom post processor
New [Custom] Mode of Test Generation
With this pr we’ve introduced a new custom
mode of test generation. You’re able to pass your own implementation of an HTTP client (you can reuse our OkHttpHttpVerifier
), thanks to which you can e.g. use HTTP/2. This was a prerequisite for the GRPC task. Thanks to the Spring Cloud Contract Workshops and the following refactoring of Spring Cloud Contract it was quite easy to add this feature, so thanks everyone involved then!
You can read more about this in the documentation.
Experimental GRPC Support
With the custom mode in place we could add the experimental GRPC support. Why experimental? Due to GRPC’s tweaking of the HTTP/2 Header frames, it’s impossible to assert the grpc-status
header. You can read more about the feature, the issue and workarounds in the documentation.
Here you can find an example of GRPC producer and of a GRPC consumer.
GraphQL Support
With this PR we’ve added GraphQL support. Since GraphQL is essentially POST to and endpoint with specific body, you can create such a contract and set the proper metadata. You can read more about this in the documentation.
Here you can find an example of GraphQL producer and of a GraphQL consumer.
Stub Runner Boot Thin JAR
With this issue we’ve migrated the Stub Runner Boot application to be a thin jar based application. Not only have we managed to lower the size of the produced artifact, but also we’re able via properties turn on profiles (e.g. kafka
or rabbit
profiles) that would fetch additional dependencies at runtime.
Messaging Polyglot Support
Pre-built kafka and amqp support
With the thin jar rewrite and this PR and this issue we’re adding support for Kafka and AMQP based solutions with the Docker images.
You’ll have to have the following prerequisites met:
- Middleware (e.g. RabbitMQ or Kafka) must be running before generating tests
- Your contract needs to call a method
triggerMessage(...)
with a String parameter that is equal to the contract’s label. - Your application needs to have a HTTP endpoint via which we can trigger a message
- That endpoint should not be available on production (could be enabled via an environment variable)
Your contract can leverage the kafka
and amqp
metadata sections like below:
description: 'Send a pong message in response to a ping message'
label: 'ping_pong'
input:
# You have to provide the `triggerMessage` method with the `label`
# as a String parameter of the method
triggeredBy: 'triggerMessage("ping_pong")'
outputMessage:
sentTo: 'output'
body:
message: 'pong'
metadata:
amqp:
outputMessage:
connectToBroker:
declareQueueWithName: "queue"
messageProperties:
receivedRoutingKey: '#'
Standalone mode
There is legitimate reason to run your contract tests against existing middleware. Some testing frameworks might give you false positive results - the test within your build passes whereas on production the communication fails.
In Spring Cloud Contract docker images we give an option to connect to existing middleware. As presented in previous subsections we do support Kafka and RabbitMQ out of the box. However, via Apache Camel Components we can support other middleware too. Let’s take a look at the following examples of usage.
Example of a contract connecting to a real RabbitMQ instance:
description: 'Send a pong message in response to a ping message'
label: 'standalone_ping_pong'
input:
triggeredBy: 'triggerMessage("ping_pong")'
outputMessage:
sentTo: 'rabbitmq:output'
body:
message: 'pong'
metadata:
standalone:
setup:
options: rabbitmq:output?queue=output&routingKey=#
outputMessage:
additionalOptions: routingKey=#&queue=output
You can read more about setting this up in this PR under the Documentation of the feature with standalone mode (aka with running middleware)
section.
Messaging with Existing Middleware
Since it’s extremely easy to start a docker image with a broker via Testcontainers, we’re suggesting to slowly migrate your messaging tests to such an approach. From the perspective of Spring Cloud Contract it’s also better since we won’t need to replicate in our code the special cases of how frameworks behave when calling a real broker. Here you can find an example of how you can connect to a JMS broker on the producer side and here how you can consume it.
Gradle Plugin rewrite
This one is fully done by the one and only shanman190. The whole work on the Gradle plugin was done by him so you should buy him a beer once you get to see him :) Anyways, there are various changes to the Gradle plugin that you can check out.
Stay in touch!
In case of any questions don’t hesitate to ping us
- On Github
- On Gitter
- On Stackoverflow
SmartTesting.pl
Wraz z Olgą Maciaszek-Sharmą i Maćkiem Aniserowiczem jesteśmy bardzo szczęsliwi mogąc ogłosić, że ruszyliśmy ze szkoleniem na temat testowania o nazwie SmartTesting! Więcej szczegółów dostępnych na stronie smarttesting.pl.
Spring Cloud Contract in the polyglot world
I have just published a new article about Spring Cloud Contract in a polyglot world at the Spring Blog. You can check it out here!.
Continuous Delivery of a Startup
Hi!
After a very long pause, finally I’ve managed to write a new blog post. It’s an interview with Jakub Kubryński about Continuous Delivery of a Startup. It’s published as part of the Java Advent Calendar.
Check it out here!.
New Project - Spring Cloud Pipelines
I’ve just published an article at the Spring blog about the creation of a new project called Spring Cloud Pipelines.
Why?
Why a new project? Cause we’ve been all doing repetitive work. Check out this post where I write about creation of a deployment pipeline. Every company does it and wastes money and resource on it. In Pivotal our goal is to give developers tools they need to deliver features as fast as possible.
Spring Cloud Pipelines gives you an opinionated deployment pipeline. You can use it straight away, you can modify it. Do whatever you please :)
Demo
The repo is setup with a demo for Concourse CI and Jenkins. Read the docs how to set it up for each of those tools. The deployment is done via Cloud Foundry. For the sake of demo we’re using PCF Dev.
Links
Spring Cloud Contract Podcast
A podcast with Michael Cote and me about Spring Cloud Contract was just published. You can check it out here!.
Spring Cloud Contract 1.0.0.RELEASE available!
I’ve just published an article at the Spring blog about Spring Cloud Contract 1.0.0.RELEASE is available.
I’m really happy that the project is GA. Even though as the Accurest project we had already done a GA release, it really feels that a lot of effort was put in order to release the GA version under the Pivotal’s Spring Cloud branding. Let’s look at some numbers:
- first commit almost 2 years ago: 2014-12-06 18:20:29 by Jakub Kubrynski - thanks to Codearte the authors of DevSkiller for their support!!!
- 1.152 commits
- 20 contributors
That’s quite a lot of work! But there we are, with a library that has already been battle-proven on production by many companies, even before being GA as Spring Cloud Contract.
What’s new in comparison to Accurest?
Like I mentioned, Accurest was already GA. So what are the main difference apart from rebranding and bug fixes?
- we’ve moved from Grapes to Aether to download stubs
- we generate fake data when you provide either consumer or producer in the DSL
- Consumer Contract approach is there
- Spring Cloud Contract is available on start.spring.io
- you can have more than one base class for your tests
- Spring Cloud Stub Runner Boot can register stubs in Eureka / Consul / Zookeeper using Spring Cloud
- the whole build was moved from Gradle to the standard Spring Cloud Maven setup
These are the Spring Cloud Contract Verifier changes. Apart from that Spring Cloud Contract consists of Spring Cloud Contract WireMock support and Spring Cloud Contract RestDocs. Thanks to the first one the integration with WireMock is much more efficient and thanks to the latter you don’t have to use the Groovy DSL - you can define your stubs by yourself by attaching them to an existing RestDocs test.
As far as Spring Cloud Contract Verifier is concerned the biggest two changes are the Consumer Contract support and that you can have more than one base class for your tests. Let’s take a closer look what’s there in the docs about them…
Consumer Contract support
Another way of storing contracts other than having them with the producer is keeping them in a common place. It can be related to security issues where the consumers can’t clone the producer’s code. Also if you keep contracts in a single place then you, as a producer, will know how many consumers you have and which consumer will you break with your local changes.
Repo structure
Let’s assume that we have a producer with coordinates com.example:server and 3 consumers: client1, client2, client3. Then in the repository with common contracts you would have the following setup (which you can checkout here:
├── com
│ └── example
│ └── server
│ ├── client1
│ │ └── expectation.groovy
│ ├── client2
│ │ └── expectation.groovy
│ ├── client3
│ │ └── expectation.groovy
│ └── pom.xml
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
└── assembly
└── contracts.xml
As you can see the under the slash-delimited groupid / artifact id folder (com/example/server
) you have expectations of the 3 consumers (client1
, client2
and client3
). Expectations are the standard Groovy DSL contract files as described throughout this documentation. This repository has to produce a JAR file that maps one to one to the contents of the repo.
Example of a pom.xml
inside the server
folder.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Server Stubs</name>
<description>POM used to install locally stubs for consumer side</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.BUILD-SNAPSHOT</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<spring-cloud-contract.version>1.0.1.BUILD-SNAPSHOT</spring-cloud-contract.version>
<spring-cloud-dependencies.version>Camden.BUILD-SNAPSHOT</spring-cloud-dependencies.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<version>${spring-cloud-contract.version}</version>
<extensions>true</extensions>
<configuration>
<!-- By default it would search under src/test/resources/ -->
<contractsDirectory>${project.basedir}</contractsDirectory>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
As you can see there are no dependencies other than the Spring Cloud Contract Verifier Maven plugin. Those poms are necessary for the consumer side to run mvn clean install -DskipTests
to locally install stubs of the producer project.
The pom.xml
in the root folder can look like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.standalone</groupId>
<artifactId>contracts</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Contracts</name>
<description>Contains all the Spring Cloud Contracts, well, contracts. JAR used by the producers to generate tests and stubs</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>contracts</id>
<phase>prepare-package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<attach>true</attach>
<descriptor>${basedir}/src/assembly/contracts.xml</descriptor>
<!-- If you want an explicit classifier remove the following line -->
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
It’s using the assembly plugin in order to build the JAR with all the contracts. Example of such setup is here:
<assembly xmlns="https://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 https://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>project</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory>
<useDefaultExcludes>true</useDefaultExcludes>
<excludes>
<exclude>**/${project.build.directory}/**</exclude>
<exclude>mvnw</exclude>
<exclude>mvnw.cmd</exclude>
<exclude>.mvn/**</exclude>
<exclude>src/**</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>
Workflow
The workflow would look similar to the one presented in the Step by step guide to CDC. The only difference is that the producer doesn’t own the contracts anymore. So the consumer and the producer have to work on common contracts in a common repository.
Consumer
When the consumer wants to work on the contracts offline, instead of cloning the producer code, the consumer team clones the common repository, goes to the required producer’s folder (e.g. com/example/server
) and runs mvn clean install -DskipTests
to install locally the stubs converted from the contracts.
REMEMBER! You need to have Maven installed locally
Producer
As a producer it’s enough to alter the Spring Cloud Contract Verifier to provide the URL and the dependency of the JAR containing the contracts:
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<configuration>
<contractsRepositoryUrl>https://link/to/your/nexus/or/artifactory/or/sth</contractsRepositoryUrl>
<contractDependency>
<groupId>com.example.standalone</groupId>
<artifactId>contracts</artifactId>
</contractDependency>
</configuration>
</plugin>
With this setup the JAR with groupid com.example.standalone
and artifactid contracts will be downloaded from https://link/to/your/nexus/or/artifactory/or/sth
. It will be then unpacked in a local temporary folder and contracts present under the com/example/server
will be picked as the ones used to generate the tests and the stubs. Due to this convention the producer team will know which consumer teams will be broken when some incompatible changes are done.
The rest of the flow looks the same.
More than one base class
That was quite a problem when providing one single base class for all the tests. After some time the mock configurations were enormous! That’s why we’ve added a possibility to map a contract to its test base class.
Gradle
If your base classes differ between contracts you can tell the Spring Cloud Contract plugin which class should get extended by the autogenerated tests. You have two options:
- follow a convention by providing the
packageWithBaseClasses
- provide explicit mapping via
baseClassMappings
Convention
The convention is such that if you have a contract under e.g. src/test/resources/contract/foo/bar/baz/
and provide the value of the packageWithBaseClasses
property to com.example.base
then we will assume that there is a BarBazBase
class under com.example.base
package. In other words we take last two parts of package if they exist and form a class with a Base
suffix. Takes precedence over baseClassForTests
. Example of usage in the contracts closure:
packageWithBaseClasses = 'com.example.base'
Mapping
You can manually map a regular expression of the contract’s package (package, not folder) to fully qualified name of the base class for the matched contract. Let’s take a look at the following example:
baseClassForTests = "com.example.FooBase"
baseClassMappings {
baseClassMapping('.*com.*', 'com.example.ComBase')
baseClassMapping('.*bar.*':'com.example.BarBase')
}
Let’s assume that you have contracts under
src/test/resources/contract/com/
src/test/resources/contract/foo/
By providing the baseClassForTests
we have a fallback in case mapping didn’t succeed (you could also provide the packageWithBaseClasses
as fallback). That way the tests generated from src/test/resources/contract/com/
contracts will be extending the com.example.ComBase
whereas the rest of tests will extend com.example.FooBase
cause they don’t match the base class mapping for bar
folder.
Maven
Let’s now look how it looks like for Maven.
Convention
To accomplish the same result as the one presented for Gradle you’d have to set your configuration like this:
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<configuration>
<packageWithBaseClasses>com.example.base</packageWithBaseClasses>
</configuration>
</plugin>
Mapping
You can manually map a regular expression of the contract’s package to fully qualified name of the base class for the matched contract. You have to provide a list baseClassMappings
of baseClassMapping
that takes a contractPackageRegex
to baseClassFQN
mapping. Let’s take a look at the following example:
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<configuration>
<baseClassForTests>com.example.FooBase</baseClassForTests>
<baseClassMappings>
<baseClassMapping>
<contractPackageRegex>.*com.*</contractPackageRegex>
<baseClassFQN>com.example.ComBase</baseClassFQN>
</baseClassMapping>
<baseClassMapping>
<contractPackageRegex>.*bar.*</contractPackageRegex>
<baseClassFQN>com.example.BarBase</baseClassFQN>
</baseClassMapping>
</baseClassMappings>
</configuration>
</plugin>
Summary
In this blog post we’ve checked what are the new and shiny features in the GA of Spring Cloud Contract. We’ve also checked some history around Accurest to Spring Cloud Contract migration.
Links
Here you can find interesting links related to Spring Cloud Contract Verifier:
Spring Cloud Contract 1.0.0.M1 Released
I’ve just published an article at the Spring blog about Spring Cloud Contract 1.0.0.M1 Release. Check out the new project formerly known as Accurest!
Accurest becomes part of the Spring Cloud Contract
I’m extremely happy to announce that we have successfully rebranded the Accurest project. It’s officially become part of the Spring Cloud Contract initiative. Ladies and Gentlemen please welcome the new projects:
A little bit of history
Accurest was created because of lack of an easy-to-use tool for doing Consumer Driven Contracts. From our production experience the biggest problem was lack of verification that the defined contract actually does what it says it does. We wanted to ensure that from the contract automatically tests are generated so that we can have a proof that the stubs are reliable. Since there was no such tool the first commit of Accurest took place on 12/2014. The very idea and its implementation was initially set by Jakub Kubrynski and me. The last available version of Accurest was 1.1.0 released on 06/2016 (the docs for the old version are available here). During these 19 months a lot of feedback has been gathered. The tool has received a lot of very good reception and that made us want to work even harder. Many times we have decided to decrease the time required for sleeping so as to fix a bug or develop a new feature in Accurest.
Notable features
Speaking of features, especially quite a few of them definitely makes Accurest stand out on the “market” of Consumer Driven Contract (CDC) tooling. Out of many the most interesting are:
- Possibility to do CDC with messaging
- Clear and easy to use, statically typed DSL
- Possibility to copy paste your current JSON file to the contract and only edit its elements
- Automatic generation of tests from the defined Contract
- Stub Runner functionality - the stubs are automatically downloaded at runtime from Nexus / Artifactory
- Spring Cloud integration - no discovery service is needed for integration tests
For more information check out my posts about Stub Runner, Accurest Messaging or just read the docs.
Spring Cloud Contract
In Pivotal we came to the conclusion that Accurest could become an interesting addition to our Spring Cloud tooling. Due to the increased interest of the community in the Consumer Driven Contracts approach we’ve decided to start the Spring Cloud Contract initiative.
Accurest became Spring Cloud Contract Verifier (note: the name might change in the future) but for the time being will remain in the Codearte repository. It’s becoming the part of Spring Cloud tooling as a mature tool with a growing community around it. Some arguments for that are that it has:
- a nice AsciiDoc documentation that was completely rewritten following users’ feedback
- active Gitter channel where we try to immediately answer any support questions
- Over 80 stars on Github and counting ;)
Since we believe very much in the Consumer Driven Contract approach we also want to do the library in a Client Driven way. That means that we (server side) are very open to your feedback (consumer side) and want you be the main driver of changes in the library.
Credits
The Accurest project would never come to life without the hard work of the Codearte developers (the order is random):
and obviously everybody who has ever commited something to the project.
Links
If you want to read more about Spring Cloud Contract Verifier just check out the following links.
- Spring Cloud Contract Verifier Github Repository
- Spring Cloud Contract Verifier Documentation
- Accurest Legacy Documentation
- Spring Cloud Contract Stub Runner Documentation
- Spring Cloud Contract Stub Runner Messaging Documentation
- Spring Cloud Contract Verifier Gitter
- Spring Cloud Contract Verifier Maven Plugin