1
votes

I am trying to update dozens of services to au.com.dius:pact-jvm-consumer-junit_2.12:3.5.12 from au.com.dius:pact-jvm-consumer-junit_2.11:3.2.13 but it seems that the new consumer version is generating pacts that the old provider version (au.com.dius:pact-jvm-provider-junit_2.11:3.2.13) cannot handle.

The old pact had a hashmap with matching rules being added at the root as show below

{
    "consumer": {
        "name": "consumer-amqp"
    },
    "provider": {
        "name": "prodvider-amqp"
    },
    "messages": [
        {
            "description": "amqp contract",
            "contents": {
                "body": {
                    "guidProperty": "795ecfd5-a3a5-430f-a0cd-1569df61bff6"
                }
            },
            "matchingRules": {
                "$.body.body.guidProperty": {
                    "regex": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
                }
            }
        }
    ],
    "metadata": {
        "pact-specification": {
            "version": "3.0.0"
        },
        "pact-jvm": {
            "version": "3.2.13"
        }
    }
}

The new consumer adds and wrapper body around the matchers. Below is an example of the same pact generated with the new consumer version

{
  "consumer": {
    "name": "consumer-amqp"
  },
  "provider": {
    "name": "prodiver-amqp"
  },
  "messages": [
    {
      "description": "contract",
      "contents": {
        "body": {
          "guidProperty": "e2490de5-5bd3-43d5-b7c4-526e33f71304"
        }
      },
      "matchingRules": {
        "body": {
          "$.guidProperty": {
            "matchers": [
              {
                "match": "regex",
                "regex": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
              }
            ],
            "combine": "AND"
          }
        }
      }
    }
  ],
  "metadata": {
    "pact-specification": {
      "version": "3.0.0"
    },
    "pact-jvm": {
      "version": "3.5.12"
    }
  }
}

Because of that change the provider fails to parse the matching rules with the following error:

body
^
10:21:24.526 [main] DEBUG au.com.dius.pact.matchers.JsonBodyMatcher - compareValues: No matcher defined for path List($, body, body, guidProperty), using equality
10:21:24.527 [main] WARN au.com.dius.pact.matchers.Matchers$ - Path expression body is invalid, ignoring: [1.1] failure: `$' expected but `b' found

java.lang.AssertionError: 

comparison

{$.body.body.guidProperty=Expected 'e2490de5-5bd3-43d5-b7c4-526e33f71304' but received 'aff876f5-5014-937c-6855-c099f9857437'

Looking at the v3 spec the new message seems to be valid, does the old provider library (v3.2.13) not support it? I looked through the code and found this commit which seems to me where the change was introduced.

From my testing the new provider library (3.5.12) can handle both old and new formats, but if both the new provider and old consumer libraries are present in the classpath http contract tests fail with run-time errors.

Questions:

1) Is there a way to force the new consumer to create the pacts the old way, and is that form spec compliant?

2) Is there a way to update the provider to the new version and still have the old consumer library in the path and not get failures?

1
Have you tried specifying pact-specification version 2 instead of 3? I'm not seeing any features that 3 would give you over 2, as 3 is still being developed. 2 is what we would consider our LTS at the moment. Please try that first to see if it works, if not, then please create an issue on the repo referencing the commit that caused the issue as this should be considered a bug. Cheers. - J_A_X
I tried version 2 and that would work for some pacts. Unfortunately, I also have message pacts that are only supported in version 3. - Yunior

1 Answers

0
votes

As J_A_X pointed out, it looks like the commit you referenced fixed a bug where pacts that were supposed to be version 3 were not fully version 3 compliant (they used the old matchers format)

1) Is there a way to force the new consumer to create the pacts the old way, and is that form spec compliant?

Yes and yes. You should be able to fix this by setting the system property pact.provider.version to 2 - then both the old and the new versions will be able to read the generated pact.

2) Is there a way to update the provider to the new version and still have the old consumer library in the path and not get failures?

Yes, as long as you ask the old consumer version to generate version 2 pacts (but ideally, why not update both to the same version?)