<commit_before># pact-sample
A sample project showing how to use Pact to implement consumer-driven tests in Groovy.

## the idea

With the increasing popularity of microservices, it can be quite hard to track the impact of a change done to a given service over consumers of this service. Consumers of this service can be other microservices or user interfaces.

A quite common setting is to have a RESTful Web API acting as a backend component to single-page app, responsible for acting as an UI to the end user. In such a setting, breaking changes can be introduced to the backend without the people responsible for the frontend being aware of it, causing disturbances to the experience provided to user.

One way of overcoming this issue is to use [Consumer-Driven Contracts](https://martinfowler.com/articles/consumerDrivenContracts.html). Such technique proposes that the consumer of the information defines a contract between itself and the producer of the information, and both parties should conform to that contract at all times.

This project is to demonstrate in a very simple and concise manner how to implement Consumer-Driven Contracts between two parties.

You'll notice there are two sub-folders here:

* **consumer**: a very simple command-line interface that accepts only one command: `status`. When invoked, this interface will connect to a backend component via HTTP, retrieve information about its availability and display it to the user. Two pieces of information should be displayed to the user: the backend status (it should be `OK` at all times, hopefully) and the date when that information was provided. Pretty basic, very very simple, our focus is **not** in showing off CLI skills, but rather to show how Consumer-Driven Contracts work on the client side.

* **producer**: a very basic Spring-Boot service, with just one endpoint (`/status`) that accepts `GET` calls. When a `GET /status` request is issued against this service, a JSON response should be sent back (e.g.: `{"status":"OK","currentDateTime":"2017-06-27T13:54:29.214"}`). Again, very basic, very simple and minimalistic, the focus is not to come up with a super fancy service, but rather to demonstrate how a backend component can comply with a contract defined by its consumers.

## the implementation

This project uses [Pact-JVM](https://github.com/DiUS/pact-jvm), a spin-off from [Pact](https://github.com/realestate-com-au/pact) to implement Consumer-Driven Contracts.

The underlying programming language chosen for both consumer and provider is Groovy.

## implementing the idea

### references

Before diving into code, I'll paste here the sources of information I've used to implement this example:
* https://github.com/DiUS/pact-jvm/tree/master/pact-jvm-consumer-groovy
* http://www.chuanchuanlaw.com/pact-how-to-write-consumer-test/
* http://www.chuanchuanlaw.com/pact-how-to-write-provider-test/
* http://dius.com.au/2016/02/03/microservices-pact/
* https://github.com/mstine/microservices-pact
* https://github.com/DiUS/pact-workshop-jvm
* https://github.com/realestate-com-au/pact-jvm-provider-spring-mvc
* https://github.com/DiUS/pact-jvm/tree/master/pact-jvm-provider-junit

### step 0: creating the project

Well, the technique is called "**Consumer-Driven** Contracts" for a reason. So I guess it makes sense to start by the consuming part of the project :)

So, to create the project, I just used Gradle to create a basic project: `gradle init --type groovy-library`. A small project containing a `Library` class, with its respective test was created.

After removing some of the code generated by Gradle and adding the dependencies to use Pact-JVM with Groovy, `build.gradle` looks like this:

```
apply plugin: 'groovy'

repositories {
    jcenter()
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.4.11'

    testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
    testCompile 'org.codehaus.groovy.modules.http-builder:http-builder:0.7'
    testCompile 'au.com.dius:pact-jvm-consumer-groovy_2.11:3.5.0'
    testCompile 'au.com.dius:pact-jvm-consumer-junit_2.11:2.1.13'
}
```

In case you're asking what's `http-builder` is doing there, it's where Groovy's `RESTClient` sits, and this will be quite handy to implement the remote calls needed for the test.

### step 1: creating the Pact

As previously stated, the consumer component...

* relies on a `/status` endpoint made available by the producer;
* expects such endpoint to accept `GET` calls and return a JSON object containing two attributes: `status` and `currentDateTime`;

Such expectations should then be clearly stated in the contract to be held between consuming and producing parties.

`StatusEndpointPact.groovy` below depicts how this contract is proposed by the consumer.

```
import org.junit.Test
import au.com.dius.pact.consumer.PactVerificationResult
import au.com.dius.pact.consumer.groovy.PactBuilder
import groovyx.net.http.RESTClient

class StatusEndpointPact {

    @Test
    void "pact for /status"() {
        def statusEndpointPact = new PactBuilder()

        statusEndpointPact {
            serviceConsumer "Status CLI" 	          // Define the service consumer by name
            hasPactWith "Status Endpoint"           // Define the service provider that the consumer has a pact with
            port 1234                               // The port number for the service. It is optional, leave it out to use a random one

            given('status endpoint is up')
            uponReceiving('a status enquiry')
            withAttributes(method: 'get', path: '/status')
            willRespondWith(
                    status: 200,
                    headers: ['Content-Type': 'application/json'],
                    body: '{"status":"OK","currentDateTime":"2017-06-27T13:54:29.214"}'
            )
        }

        // Execute the run method to have the mock server run.
        // It takes a closure to execute your requests and returns a PactVerificationResult.
        PactVerificationResult result = statusEndpointPact.runTest {
            def client = new RESTClient('http://localhost:1234/')
            def response = client.get(path: '/status')

            assert response.status == 200
            assert response.contentType == 'application/json'
            assert response.data.status == 'OK'
        }

        assert result == PactVerificationResult.Ok.INSTANCE  // This means it is all good
    }
}
```
(You'll notice my example has **a lot** in common with the example proposed on https://github.com/DiUS/pact-jvm/tree/master/pact-jvm-consumer-groovy :) )

From this point, you have your first consumer-driven test. To run it, simply right-click the class on your favourite IDE and run it. No need to rely on special fancy Gradle commands, any regular test running mechanism will do.

As soon as you run this test, a new file will be created: `target/Status CLI-Status Endpoint.json`. This file describes the contract both parties should comply with it, along with Pact-specific metadata.

Having something generated under `/target` on a Gradle project sounds rather funky. You can customize this via system properties. Suppose you want generated pacts to be placed under Gradle's regular `/build` folder, or under `/build/pacts`. Just invoke your test using `-Dpact.rootDir="build/pacts"`. Or if you rather have this configured at `build.gradle`, add the following block:

```
test {
    systemProperties['pact.rootDir'] = "$buildDir/pacts"
}
```

### step 2: making the Pact available to the producer

After having the Pact contract defined by the consumer, it makes sense to have the producer comply to it, no? So, the next step is having both the consumer and the producer look at the same contract.

If you look at https://github.com/DiUS/pact-jvm/tree/master/pact-jvm-consumer-groovy and  https://github.com/DiUS/pact-jvm/tree/master/pact-jvm-provider-junit, there a few ways to implement this:

1. The best approach is to have your contracts available at some kind of broker. https://github.com/DiUS/pact-jvm/tree/master/pact-jvm-consumer-groovy#publishing-your-pact-files-to-a-pact-broker talks a little bit about it. In this setting, as soon as a pact is generated, it's uploaded to Pact broker, from which the producer can afterwards download the same pact and make sure the contract is being complied with. https://github.com/DiUS/pact-jvm/tree/master/pact-jvm-provider-junit#download-pacts-from-a-pact-broker shows how to dowload a Pact file from a broker;
<commit_msg>add consumer production code to README<commit_after># pact-sample
A sample project showing how to use Pact to implement consumer-driven tests in Groovy.

## the idea

With the increasing popularity of microservices, it can be quite hard to track the impact of a change done to a given service over consumers of this service. Consumers of this service can be other microservices or user interfaces.

A quite common setting is to have a RESTful Web API acting as a backend component to single-page app, responsible for acting as an UI to the end user. In such a setting, breaking changes can be introduced to the backend without the people responsible for the frontend being aware of it, causing disturbances to the experience provided to user.

One way of overcoming this issue is to use [Consumer-Driven Contracts](https://martinfowler.com/articles/consumerDrivenContracts.html). Such technique proposes that the consumer of the information defines a contract between itself and the producer of the information, and both parties should conform to that contract at all times.

This project is to demonstrate in a very simple and concise manner how to implement Consumer-Driven Contracts between two parties.

You'll notice there are two sub-folders here:

* **consumer**: a very simple command-line interface that accepts only one command: `status`. When invoked, this interface will connect to a backend component via HTTP, retrieve information about its availability and display it to the user. Two pieces of information should be displayed to the user: the backend status (it should be `OK` at all times, hopefully) and the date when that information was provided. Pretty basic, very very simple, our focus is **not** in showing off CLI skills, but rather to show how Consumer-Driven Contracts work on the client side.

* **producer**: a very basic Spring-Boot service, with just one endpoint (`/status`) that accepts `GET` calls. When a `GET /status` request is issued against this service, a JSON response should be sent back (e.g.: `{"status":"OK","currentDateTime":"2017-06-27T13:54:29.214"}`). Again, very basic, very simple and minimalistic, the focus is not to come up with a super fancy service, but rather to demonstrate how a backend component can comply with a contract defined by its consumers.

## the implementation

This project uses [Pact-JVM](https://github.com/DiUS/pact-jvm), a spin-off from [Pact](https://github.com/realestate-com-au/pact) to implement Consumer-Driven Contracts.

The underlying programming language chosen for both consumer and provider is Groovy.

## implementing the idea

### references

Before diving into code, I'll paste here the sources of information I've used to implement this example:
* https://github.com/DiUS/pact-jvm/tree/master/pact-jvm-consumer-groovy
* http://www.chuanchuanlaw.com/pact-how-to-write-consumer-test/
* http://www.chuanchuanlaw.com/pact-how-to-write-provider-test/
* http://dius.com.au/2016/02/03/microservices-pact/
* https://github.com/mstine/microservices-pact
* https://github.com/DiUS/pact-workshop-jvm
* https://github.com/realestate-com-au/pact-jvm-provider-spring-mvc
* https://github.com/DiUS/pact-jvm/tree/master/pact-jvm-provider-junit

### step 0: creating the project

Well, the technique is called "**Consumer-Driven** Contracts" for a reason. So I guess it makes sense to start by the consuming part of the project :)

So, to create the project, I just used Gradle to create a basic project: `gradle init --type groovy-library`. A small project containing a `Library` class, with its respective test was created.

After removing some of the code generated by Gradle and adding the dependencies to use Pact-JVM with Groovy, `build.gradle` looks like this:

```
apply plugin: 'groovy'

repositories {
    jcenter()
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.4.11'

    testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
    testCompile 'org.codehaus.groovy.modules.http-builder:http-builder:0.7'
    testCompile 'au.com.dius:pact-jvm-consumer-groovy_2.11:3.5.0'
    testCompile 'au.com.dius:pact-jvm-consumer-junit_2.11:2.1.13'
}
```

In case you're asking what's `http-builder` is doing there, it's where Groovy's `RESTClient` sits, and this will be quite handy to implement the remote calls needed for the test.

### step 1: creating the Pact

As previously stated, the consumer component...

* relies on a `/status` endpoint made available by the producer;
* expects such endpoint to accept `GET` calls and return a JSON object containing two attributes: `status` and `currentDateTime`;

Such expectations should then be clearly stated in the contract to be held between consuming and producing parties.

`StatusEndpointPact.groovy` below depicts how this contract is proposed by the consumer.

```
import org.junit.Test
import au.com.dius.pact.consumer.PactVerificationResult
import au.com.dius.pact.consumer.groovy.PactBuilder
import groovyx.net.http.RESTClient

class StatusEndpointPact {

    @Test
    void "pact for /status"() {
        def statusEndpointPact = new PactBuilder()

        statusEndpointPact {
            serviceConsumer "Status CLI" 	          // Define the service consumer by name
            hasPactWith "Status Endpoint"           // Define the service provider that the consumer has a pact with
            port 1234                               // The port number for the service. It is optional, leave it out to use a random one

            given('status endpoint is up')
            uponReceiving('a status enquiry')
            withAttributes(method: 'get', path: '/status')
            willRespondWith(
                    status: 200,
                    headers: ['Content-Type': 'application/json'],
                    body: '{"status":"OK","currentDateTime":"2017-06-27T13:54:29.214"}'
            )
        }

        // Execute the run method to have the mock server run.
        // It takes a closure to execute your requests and returns a PactVerificationResult.
        PactVerificationResult result = statusEndpointPact.runTest {
            def client = new RESTClient('http://localhost:1234/')
            def response = client.get(path: '/status')

            assert response.status == 200
            assert response.contentType == 'application/json'
            assert response.data.status == 'OK'
        }

        assert result == PactVerificationResult.Ok.INSTANCE  // This means it is all good
    }
}
```
(You'll notice my example has **a lot** in common with the example proposed on https://github.com/DiUS/pact-jvm/tree/master/pact-jvm-consumer-groovy :) )

From this point, you have your first consumer-driven test. To run it, simply right-click the class on your favourite IDE and run it. No need to rely on special fancy Gradle commands, any regular test running mechanism will do.

As soon as you run this test, a new file will be created: `target/Status CLI-Status Endpoint.json`. This file describes the contract both parties should comply with it, along with Pact-specific metadata.

Having something generated under `/target` on a Gradle project sounds rather funky. You can customize this via system properties. Suppose you want generated pacts to be placed under Gradle's regular `/build` folder, or under `/build/pacts`. Just invoke your test using `-Dpact.rootDir="build/pacts"`. Or if you rather have this configured at `build.gradle`, add the following block:

```
test {
    systemProperties['pact.rootDir'] = "$buildDir/pacts"
}
```

### step 1.1: making some sense out of consumer needs

It's a bit weird to just define a contract without an use case to back it up, right?

As previously stated, the consumer is supposed to be "a very simple command-line interface that accepts only one command: `status`". So, just to add more context and improving understanding of the consumer needs, the classes below depict what the consumer offers. (Please notice this requires you to go back to `build.gradle` and change `http-builder` to be a `compile` dependency, instead of `testCompile`).

These are the classes on the consumer project:

**Main**
```
package com.github.felipecao.pactsample

import com.github.felipecao.pactsample.cli.CommandLineInterface
import com.github.felipecao.pactsample.provider.StatusClient

class Main {
    static void main(String[] args) {
        StatusClient statusClient = new StatusClient()
        InputStream inputStream = System.in
        CommandLineInterface cli = new CommandLineInterface(statusClient, inputStream)

        cli.run()
    }
}
```

**CommandLineInterface**
```
package com.github.felipecao.pactsample.cli

import com.github.felipecao.pactsample.provider.StatusClient

class CommandLineInterface {

    private static final STATUS_COMMAND = "status"

    private static final QUIT_COMMAND = "quit"

    private StatusClient statusClient

    private InputStream inputStream

    CommandLineInterface(StatusClient statusClient, InputStream inputStream = null) {
        this.statusClient = statusClient
        this.inputStream = inputStream ?: System.in
    }

    void run() {
        inputStream.withReader {
            while (true) {
                String userCommand = readUserInput(it)

                if (userCommand.equalsIgnoreCase(QUIT_COMMAND)) {
                    System.exit(0)
                }

                if (!userCommand.equalsIgnoreCase(STATUS_COMMAND)) {
                    println("Command '${userCommand}' is not supported. Try '${STATUS_COMMAND}' or '${QUIT_COMMAND}' instead.")
                    continue
                }

                println(statusClient.retrieveProviderStatus())
            }
        }
    }

    private String readUserInput(Reader reader) {
        print "Enter command: "
        return reader.readLine().trim()
    }
}
```

**StatusClient**
```
package com.github.felipecao.pactsample.provider

import groovyx.net.http.RESTClient

class StatusClient {
    private static final String BASE_URL = "http://localhost:8080"
    private RESTClient restClient

    StatusClient() {
        this.restClient = new RESTClient(BASE_URL)
    }

    def retrieveProviderStatus() {
        restClient.get([path: '/status']).data
    }
}
```

### step 2: making the Pact available to the producer

After having the Pact contract defined by the consumer, it makes sense to have the producer comply to it, no? So, the next step is having both the consumer and the producer look at the same contract.

If you look at https://github.com/DiUS/pact-jvm/tree/master/pact-jvm-consumer-groovy and  https://github.com/DiUS/pact-jvm/tree/master/pact-jvm-provider-junit, there a few ways to implement this:

1. The best approach is to have your contracts available at some kind of broker. https://github.com/DiUS/pact-jvm/tree/master/pact-jvm-consumer-groovy#publishing-your-pact-files-to-a-pact-broker talks a little bit about it. In this setting, as soon as a pact is generated, it's uploaded to Pact broker, from which the producer can afterwards download the same pact and make sure the contract is being complied with. https://github.com/DiUS/pact-jvm/tree/master/pact-jvm-provider-junit#download-pacts-from-a-pact-broker shows how to dowload a Pact file from a broker;

{'fraction_non_alphanumeric': 0.08504398826979472, 'fraction_numerical': 0.008747092729295176, 'mean_word_length': 3.576353540027765, 'pattern_counts': {'":': 8, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 26, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5572949', 'n_tokens_mistral': 5604, 'n_tokens_neox': 5281, 'n_words': 2215}