Skip to content

SlandShow/PACT-Broker-Example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 

Repository files navigation

PACT-Broker-Example

PACT is a contract testing tool. It helps to test communications between services/microservices. But the main idea of this repository is different. This is manual how to use PACT Broker with Maven in Spring Boot.

If you want more information about PACT - follow next docs.

Consumer

Consumer - A client that wants to receive some data.

Here is an example of how consumer share pact files on broker:

          <plugin>
                <groupId>au.com.dius</groupId>
                <artifactId>pact-jvm-provider-maven_2.12</artifactId>
                <version>3.5.11</version>
                <executions>
                    <execution>
                        <phase>install</phase>
                        <goals>
                            <goal>publish</goal>
                        </goals>
                        <!-- Run broker on local machine with docker using docker-compose file -->
                        <configuration>
                            <pactDirectory>${basedir}/target/pacts</pactDirectory>
                            <pactBrokerUrl>http://localhost:80</pactBrokerUrl>
                            <projectVersion>1.1</projectVersion>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Consumer test generate json in target file, when it exetutes via Spring Boot context. And next step on maven plugin, which share this json on broker. It's pretty easy and can be executed in CI Job.

Usage of Consumer

Build Comsumer:

mvn clean install

Then run:

mvn spring-boot:run

Consumer application have swagger-ui is available on http://localhost:8080/swagger-ui.html

Example of Consumer interaction on broker: broker not found

Provider

Provider - a service or server that provides the data.

Provider must verify interaction from broker. If interaction succesfully verified - broker mark it via green color, if not - via red color. For more info, read next part of documentation.

Usage of Provider

Build Provider:

mvn clean install

If you want to verify interaction on briker, first run application:

mvn spring-boot:run

And in additional terminal use plugin to verify:

mvn pact:verify

It's important, because naven plugin for verify PACT works upon of Spring Boot application context. The oddity is that when performing Spring Boot tests with a raised context, the consumer still takes the JSON from the broker. Only except for the fact that he does not mark them as "verified".

Provider application have swagger-ui is available on http://localhost:7073/swagger-ui.html

Broker

The Pact Broker is an application for sharing for consumer driven contracts and verification results. It is optimised for use with "pacts" (contracts created by the Pact framework), but can be used for any type of contract that can be serialized to JSON.

More info available here.

For example.

  1. Empty Broker:

broker not found

  1. Broker with consumer interaction:

broker not found

  1. Broker with verified consumer interaction:

broker not found

HTTP PACT publishing & retrieving

We can use HTTP REST calls to broker. You most likely won't need to get your hands dirty with curl however, as pact publishing is built in to most of the native pact libraries already.

For example:

  1. cd Consumer

  2. In console use next cUrl:

curl -v -XPUT -H "Content-Type: application/json" -d@foo-bar.json http://localhost:80/pacts/provider/Bar/consumer/Foo/version/1.0.0+4jvh387gj3

How to run PACT Broker on my local machine?

Just use docker compose:

docker-compose --file docker-compose-pact.yaml  up --build

And then open: http://localhost:80

Swagger codegen

In this example swagger definition used for API generation. Here we generate YAML swagger definition for Provider (swagger file located in target folder):

             <plugin>
                <groupId>com.github.kongchen</groupId>
                <artifactId>swagger-maven-plugin</artifactId>
                <version>3.1.7</version>
                <configuration>
                    <apiSources>
                        <apiSource>
                            <springmvc>true</springmvc>
                            <locations>
                                <location>com.slandshow.demo</location>
                            </locations>
                            <outputFormats>yaml</outputFormats>
                            <schemes>
                                <scheme>http</scheme>
                            </schemes>
                            <info>
                                <title>PACT Provider</title>
                                <version>1.0</version>
                                <description>Nothing</description>
                            </info>
                            <swaggerDirectory>${basedir}/target/swagger/temp</swaggerDirectory>
                            <swaggerApiReader>com.github.kongchen.swagger.docgen.reader.SpringMvcApiReader
                            </swaggerApiReader>
                            <swaggerFileName>internal-swagger</swaggerFileName>
                        </apiSource>
                    </apiSources>
                </configuration>
                <executions>
                    <execution>
                        <configuration>
                            <apiSources>
                                <apiSource>
                                    <locations>
                                        <location>com.slandshow.demo</location>
                                    </locations>
                                    <swaggerFileName>internal-swagger</swaggerFileName>
                                </apiSource>
                            </apiSources>
                        </configuration>
                        <id>internal-generation</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

And in Consumer we generate code via maven plugin according on this YAML swagger file:

            <plugin>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-codegen-maven-plugin</artifactId>
                <version>2.2.3</version>
                <executions>
                    <execution>
                        <id>generate-swagger-javaclient</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <!-- In enterprise projects this swagger yaml specification must be verified from Nexus-->
                            <!-- But here it just hardcored -->
                            <inputSpec>${basedir}/src/main/resources/api.yaml</inputSpec>
                            <language>java</language>
                            <generateApiTests>false</generateApiTests>
                            <generateModelTests>false</generateModelTests>
                            <library>resttemplate</library>
                            <modelPackage>${project.groupId}.client.model</modelPackage>
                            <apiPackage>${project.groupId}.client.api</apiPackage>
                            <invokerPackage>${project.groupId}.client.invoker</invokerPackage>
                            <importMappings>
                                <importMapping>ByteArrayResource=org.springframework.core.io.ByteArrayResource
                                </importMapping>
                            </importMappings>
                            <configOptions>
                                <dateLibrary>java8-localdatetime</dateLibrary>
                            </configOptions>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

So, Provider generates RestTemplate api for Consumer. We can invoke Provider from Consumer using this generated client api. This is a main idea for communication between two microservices.

How can i use this example?

  1. Run Broker

  2. Run Consumer

  3. Run Provider

Releases

No releases published

Packages

No packages published

Languages