Files
spring-cloud-contract/spring-cloud-contract-stub-runner
Marcin Grzejszczak 251e160e9b Added starters
fixes #40
2016-07-20 14:35:12 +02:00
..
2016-07-20 14:35:12 +02:00
2016-07-19 19:50:23 +02:00
2016-07-19 19:22:32 +02:00

=== Stub Runner Core

Runs stubs for service collaborators. Treating stubs as contracts of services allows to use stub-runner as an implementation of 
http://martinfowler.com/articles/consumerDrivenContracts.html[Consumer Driven Contracts].

Stub Runner allows you to automatically download the stubs of the provided dependencies, start WireMock servers for them and feed them with proper stub definitions.
For messaging, special stub routes are defined.

==== Running stubs

===== Running using main app

You can set the following options to the main class:

[source,groovy,indent=0]
----
 -maxp (--maxPort) N            : Maximum port value to be assigned to the
                                  Wiremock instance. Defaults to 15000
                                  (default: 15000)
 -minp (--minPort) N            : Minimal port value to be assigned to the
                                  Wiremock instance. Defaults to 10000
                                  (default: 10000)
 -s (--stubs) VAL               : Comma separated list of Ivy representation of
                                  jars with stubs. Eg. groupid:artifactid1,group
                                  id2:artifactid2:version:classifier
 -sr (--stubRepositoryRoot) VAL : Location of a Jar containing server where you
                                  keep your stubs (e.g. http://nexus.net/content
                                  /repositories/repository)
 -ss (--stubsSuffix) VAL        : Suffix for the jar containing stubs (e.g.
                                  'stubs' if the stub jar would have a 'stubs'
                                  classifier for stubs: foobar-stubs ).
                                  Defaults to 'stubs' (default: stubs)
 -wo (--workOffline)            : Switch to work offline. Defaults to 'false'
                                  (default: false)
----

===== HTTP Stubs

Stubs are defined in JSON documents, whose syntax is defined in http://wiremock.org/stubbing.html[WireMock documentation]

Example:

[source,javascript,indent=0]
----
{
    "request": {
        "method": "GET",
        "url": "/ping"
    },
    "response": {
        "status": 200,
        "body": "pong",
        "headers": {
            "Content-Type": "text/plain"
        }
    }
}
----

===== Viewing registered mappings

Every stubbed collaborator exposes list of defined mappings under `__/admin/` endpoint.

===== Messaging Stubs

Depending on the provided Stub Runner dependency and the DSL the messaging routes are automatically set up.

=== Stub Runner JUnit Rule

Stub Runner comes with a JUnit rule thanks to which you can very easily download and run stubs for given group and artifact id:

[source,java,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java[tags=classrule]
----

After that rule gets executed Stub Runner connects to your Maven repository and for the given list of dependencies tries to:

- download them
- cache them locally
- unzip them to a temporary folder
- start a WireMock server for each Maven dependency on a random port from the provided range of ports / provided port
- feed the WireMock server with all JSON files that are valid WireMock definitions

Stub Runner uses https://wiki.eclipse.org/Aether[Eclipse Aether] mechanism to download the Maven dependencies. 
Check their https://wiki.eclipse.org/Aether[docs] for more information.

Since the `StubRunnerRule` implements the `StubFinder` it allows you to find the started stubs:

[source,groovy,indent=0]
----
include::src/main/java/org/springframework/cloud/contract/stubrunner/StubFinder.java[]
----

Example of usage in Spock tests:

[source,groovy,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleSpec.groovy[tags=classrule]
----

Example of usage in JUnit tests:

[source,java,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java[tags=test]
----

Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner.

==== Providing fixed ports

You can also run your stubs on fixed ports. You can do it in two different ways. One is to pass it in the properties, and the other via fluent API of
JUnit rule.

==== Fluent API

When using the `StubRunnerRule` you can add a stub to download and then pass the port for the last downloaded stub.

[source,java,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java[tags=classrule_with_port]
----

You can see that for this example the following test is valid:

[source,java,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java[tags=test_with_port]
----

==== Stub Runner Spring

Sets up Spring configuration of the Stub Runner project.

By providing a list of stubs inside your configuration file the Stub Runner automatically downloads 
and registers in WireMock the selected stubs.

If you want to find the URL of your stubbed dependency you can autowire the `StubFinder` interface and use
its methods as presented below:

[source,groovy,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy[tags=test]
----

for the following configuration file:

[source,yml,indent=0]
----
include::src/test/resources/application.yml[]
----

=== Stub Runner Spring Cloud

Registers the stubs in the provided Service Discovery. It's enough to add the jar

[source,groovy,indent=0]
----
org.springframework.cloud:stub-runner-spring-cloud
----

and the Stub Runner autoconfiguration should be picked up.

==== Stubbing Service Discovery

The most important feature of `Stub Runner Spring Cloud` is the fact that it's stubbing

- `DiscoveryClient`
- `Ribbon` `ServerList`

that means that regardles of the fact whether you're using Zookeeper, Consul, Eureka or anything else, you don't need that in your tests.
We're starting WireMock instances of your dependencies and we're telling your application whenever you're using `Feign`, load balanced `RestTemplate`
or `DiscoveryClient` directly, to call those stubbed servers instead of calling the real Service Discovery tool.

==== Additional Configuration

You can match the artifactId of the stub with the name of your app by using the `stubrunner.stubs.idsToServiceIds:` map.
You can disable Stub Runner Ribbon support by providing: `stubrunner.cloud.ribbon.enabled` equal to `false`
You can disable Stub Runner support by providing: `stubrunner.cloud.enabled` equal to `false`

=== Stub Runner Boot

Spring Cloud Contract Verifier Stub Runner Boot is a Spring Boot application that exposes REST endpoints to
trigger the messaging labels and to access started WireMock servers.

One of the usecases is to run some smoke (end to end) tests on a deployed application. You can read
 more about this in the  http://toomuchcoding.com/blog/2015/09/27/microservice-deployment/["Microservice Deployment" article at Too Much Coding blog.]

==== How to use it?

Just add the

[source,groovy,indent=0]
----
compile "org.springframework.cloud:spring-cloud-stub-runner"
----

and (optionally) a messaging implementation:

[source,groovy,indent=0]
----
// for Apache Camel
compile "org.springframework.cloud:spring-cloud-contract-stub-runner-camel"
// for Spring Integration
compile "org.springframework.cloud:spring-cloud-contract-stub-runner-integration"
// for Spring Cloud Stream
compile "org.springframework.cloud:spring-cloud-contract-stub-runner-stream"
----

Build a fat-jar with `@EnableStubRunnerServer` and you're ready to go!

For the properties check the *Stub Runner Spring* section.

==== Endpoints

===== HTTP

- GET `/stubs` - returns a list of all running stubs in `ivy:integer` notation
- GET `/stubs/{ivy}` - returns a port for the given `ivy` notation (when calling the endpoint `ivy` can also be `artifactId` only)

===== Messaging

For Messaging

- GET `/triggers` - returns a list of all running labels in `ivy : [ label1, label2 ...]` notation
- POST `/triggers/{label}` - executes a trigger with `label`
- POST `/triggers/{ivy}/{label}` - executes a trigger with `label` for the given `ivy` notation (when calling the endpoint `ivy` can also be `artifactId` only)

==== Example

[source,groovy,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/server/StubRunnerBootSpec.groovy[tags=boot_usage]
----