Search code examples
spring-cloudgradle-pluginspring-cloud-contract

How to pass custom ContractConverter to spring cloud contract docker image


I want to use a custom ContractConverter to add custom fields to my contracts. But the spring cloud contract plugin does not takes the CustomContractConverter class I have created to process the contracts.

I have created a demo project in github to demonstrate this: https://github.com/javiersvg/custom-contracts

Code structure:

- src
  - test
    - resource
      - contracts
        - helath.yml                      -> A contract with a custom field.
      - META-INF
        - spring.factories                -> Custom contract converter configuration
    - groovy/com/.../
      - CustomContractConverter.groovy    -> Custom contract converter

How to run:

There is a docker-compose.yml file which copies the content of these folders into the springcloud/spring-cloud-contract:2.2.0.BUILD-SNAPSHOT docker image and runs the generateContractTests task to create the tests based on the contracts.

Expected result:

An exception is thrown when the CustomContractConverter is called.

Actual result:

The process finishes with an exception due to the default YamlContracConverter class not being able to interprete the custom field in the contract.

What I have discovered so far:

Debugging the spring contract gradle plugin within the docker container (by adding the -Dorg.gradle.debug=true parameter to the docker-compose.yml command field) I see that the class SpringFactoriesLoader(Line: 132) which should load the spring.factories file is only loading files with that name from the jars defined as dependencies and not the one I added in the source code. This is done through the VisitableUrlClassLoader which has the reference to the dependency jars and not the source code. This is provably caused because the plugin does not load the source code until after it creates the contracts but this is only a theory.

Any experience with custom contract converters will be really appreciated.


Solution

  • You have to build your own image with that file being on the classpath. Your groovy file needs to be compiled. We don't read scripts at runtime to retrieve additional converters