spring-cloud / spring-cloud-contract

Support for Consumer Driven Contracts in Spring
https://cloud.spring.io/spring-cloud-contract
Apache License 2.0
720 stars 438 forks source link

Client Service Fails POST Test #731

Closed kpb closed 6 years ago

kpb commented 6 years ago

Not sure If I'm doing something wrong here. I have a contract:

  request {
    url '/ephemerides'
    method POST()
    headers {
      contentType applicationJson()
    }
    body(file('propagation-request.json'))
  }

The json file looks like:

{
  "start": "2018-03-09T00:01:32.656Z",
  "stop": "2018-03-09T00:01:39.656Z",
  "interval": 1000,
  "elementSet": {
    "satelliteNumber": 23670,
    "elementNumber": 999,
    "epochYear": 17,
    "revolutionAtEpoch": 7885,
    "epochDay": 99.51506375,
    "firstDerivativeMeanMotion": -5.4E-7,
    "secondDerivativeMeanMotion": 0.0,
    "bstarDragTerm": 0.0,
    "inclination": 0.18693348953485267,
    "rightAscensionAscendingNode": 0.6581060650617457,
    "eccentricity": 4.684E-4,
    "argumentOfPerigee": 4.777837082005226,
    "meanAnomaly": 5.53182280952528,
    "meanMotion": 1.00248515,
    "internationalDesignator": "95049A  ",
    "processed": true,
    "committed": true,
    "satelliteClassification": "U",
    "typeOfEphemeris": "SGP"
  }
}

I publish my stub jars and on the client side, POST the same json request (file copied into consumer project). The test fails and here is the stdout:

                                               Request was not matched
                                               =======================

-----------------------------------------------------------------------------------------------------------------------
| Closest stub                                             | Request                                                  |
-----------------------------------------------------------------------------------------------------------------------
                                                           |
POST                                                       | POST
/ephemerides                                               | /ephemerides
                                                           |
Content-Type [matches] : application/json.*                | Content-Type: application/json;charset=UTF-8
                                                           |
$.['elementSet'][?(@.['firstDerivativeMeanMotion'] ==      | {"start":"2018-03-09T00:01:32.656Z","stop":"2018-03-09T00<<<<< Body does not match
-5.4E-7)]                                                  | :01:39.656Z","interval":1000,"elementSet":{"satelliteNumb
                                                           | er":23670,"elementNumber":999,"epochYear":17,"epochDay":9
                                                           | 9.51506375,"revolutionAtEpoch":7885,"firstDerivativeMeanM
                                                           | otion":-5.4E-7,"secondDerivativeMeanMotion":0.0,"bstarDra
                                                           | gTerm":0.0,"inclination":0.18693348953485267,"rightAscens
                                                           | ionAscendingNode":0.6581060650617457,"eccentricity":4.684
                                                           | E-4,"argumentOfPerigee":4.777837082005226,"meanAnomaly":5
                                                           | .53182280952528,"meanMotion":1.00248515,"internationalDes
                                                           | ignator":"95049A 
                                                           | ","satelliteClassification":"U","typeOfEphemeris":"SGP"}}
$.['elementSet'][?(@.['processed'] == true)]               | {"start":"2018-03-09T00:01:32.656Z","stop":"2018-03-09T00<<<<< Body does not match
                                                           | :01:39.656Z","interval":1000,"elementSet":{"satelliteNumb
                                                           | er":23670,"elementNumber":999,"epochYear":17,"epochDay":9
                                                           | 9.51506375,"revolutionAtEpoch":7885,"firstDerivativeMeanM
                                                           | otion":-5.4E-7,"secondDerivativeMeanMotion":0.0,"bstarDra
                                                           | gTerm":0.0,"inclination":0.18693348953485267,"rightAscens
                                                           | ionAscendingNode":0.6581060650617457,"eccentricity":4.684
                                                           | E-4,"argumentOfPerigee":4.777837082005226,"meanAnomaly":5
                                                           | .53182280952528,"meanMotion":1.00248515,"internationalDes
                                                           | ignator":"95049A 
                                                           | ","satelliteClassification":"U","typeOfEphemeris":"SGP"}}
$.['elementSet'][?(@.['committed'] == true)]               | {"start":"2018-03-09T00:01:32.656Z","stop":"2018-03-09T00<<<<< Body does not match
                                                           | :01:39.656Z","interval":1000,"elementSet":{"satelliteNumb
                                                           | er":23670,"elementNumber":999,"epochYear":17,"epochDay":9
                                                           | 9.51506375,"revolutionAtEpoch":7885,"firstDerivativeMeanM
                                                           | otion":-5.4E-7,"secondDerivativeMeanMotion":0.0,"bstarDra
                                                           | gTerm":0.0,"inclination":0.18693348953485267,"rightAscens
                                                           | ionAscendingNode":0.6581060650617457,"eccentricity":4.684
                                                           | E-4,"argumentOfPerigee":4.777837082005226,"meanAnomaly":5
                                                           | .53182280952528,"meanMotion":1.00248515,"internationalDes
                                                           | ignator":"95049A 
                                                           | ","satelliteClassification":"U","typeOfEphemeris":"SGP"}}
                                                           |
-----------------------------------------------------------------------------------------------------------------------

2018-09-13 16:03:53.487  INFO 28416 --- [qtp450309598-27] WireMock                                 : Request received:
127.0.0.1 - POST /ephemerides

Accept: [text/plain, text/plain, application/json, application/json, application/*+json, application/*+json, */*, */*]
Connection: [keep-alive]
User-Agent: [Apache-HttpClient/4.5.6 (Java/1.8.0_181)]
Host: [localhost:8082]
Accept-Encoding: [gzip,deflate]
Content-Length: [588]
Content-Type: [application/json;charset=UTF-8]
{"start":"2018-03-09T00:01:32.656Z","stop":"2018-03-09T00:01:39.656Z","interval":1000,"elementSet":{"satelliteNumber":23670,"elementNumber":999,"epochYear":17,"epochDay":99.51506375,"revolutionAtEpoch":7885,"firstDerivativeMeanMotion":-5.4E-7,"secondDerivativeMeanMotion":0.0,"bstarDragTerm":0.0,"inclination":0.18693348953485267,"rightAscensionAscendingNode":0.6581060650617457,"eccentricity":4.684E-4,"argumentOfPerigee":4.777837082005226,"meanAnomaly":5.53182280952528,"meanMotion":1.00248515,"internationalDesignator":"95049A  ","satelliteClassification":"U","typeOfEphemeris":"SGP"}}

Matched response definition:
(no response definition configured)

Response:
HTTP/1.1 404
(no headers)

2018-09-13 16:03:53.496  INFO 28416 --- [qtp450309598-27] WireMock : Received request to /not-matched with body 
2018-09-13 16:03:53.512  INFO 28416 --- [qtp450309598-27] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['firstDerivativeMeanMotion'] == -5.4E-7)]' failed to match document '{"start":"2018-03-09T00:01:32.656Z","stop":"2018-03-09T00:01:39.656Z","interval":1000,"elementSet":{"satelliteNumber":23670,"elementNumber":999,"epochYear":17,"epochDay":99.51506375,"revolutionAtEpoch":7885,"firstDerivativeMeanMotion":-5.4E-7,"secondDerivativeMeanMotion":0.0,"bstarDragTerm":0.0,"inclination":0.18693348953485267,"rightAscensionAscendingNode":0.6581060650617457,"eccentricity":4.684E-4,"argumentOfPerigee":4.777837082005226,"meanAnomaly":5.53182280952528,"meanMotion":1.00248515,"internationalDesignator":"95049A  ","satelliteClassification":"U","typeOfEphemeris":"SGP"}}' because of error 'Expected character: )'
2018-09-13 16:03:53.517  INFO 28416 --- [qtp450309598-27] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['firstDerivativeMeanMotion'] == -5.4E-7)]' failed to match document '{"start":"2018-03-09T00:01:32.656Z","stop":"2018-03-09T00:01:39.656Z","interval":1000,"elementSet":{"satelliteNumber":23670,"elementNumber":999,"epochYear":17,"epochDay":99.51506375,"revolutionAtEpoch":7885,"firstDerivativeMeanMotion":-5.4E-7,"secondDerivativeMeanMotion":0.0,"bstarDragTerm":0.0,"inclination":0.18693348953485267,"rightAscensionAscendingNode":0.6581060650617457,"eccentricity":4.684E-4,"argumentOfPerigee":4.777837082005226,"meanAnomaly":5.53182280952528,"meanMotion":1.00248515,"internationalDesignator":"95049A  ","satelliteClassification":"U","typeOfEphemeris":"SGP"}}' because of error 'Expected character: )'
2018-09-13 16:03:53.519  INFO 28416 --- [qtp450309598-27] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['firstDerivativeMeanMotion'] == -5.4E-7)]' failed to match document '{"start":"2018-03-09T00:01:32.656Z","stop":"2018-03-09T00:01:39.656Z","interval":1000,"elementSet":{"satelliteNumber":23670,"elementNumber":999,"epochYear":17,"epochDay":99.51506375,"revolutionAtEpoch":7885,"firstDerivativeMeanMotion":-5.4E-7,"secondDerivativeMeanMotion":0.0,"bstarDragTerm":0.0,"inclination":0.18693348953485267,"rightAscensionAscendingNode":0.6581060650617457,"eccentricity":4.684E-4,"argumentOfPerigee":4.777837082005226,"meanAnomaly":5.53182280952528,"meanMotion":1.00248515,"internationalDesignator":"95049A  ","satelliteClassification":"U","typeOfEphemeris":"SGP"}}' because of error 'Expected character: )'
2018-09-13 16:03:53.611  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['typeOfEphemeris'] == 'SGP')]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.611  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['revolutionAtEpoch'] == 7885)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.612  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['meanMotion'] == 1.00248515)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.612  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['inclination'] == 0.18693348953485267)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.612  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['argumentOfPerigee'] == 4.777837082005226)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.612  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['secondDerivativeMeanMotion'] == 0.0)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.612  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['bstarDragTerm'] == 0.0)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.613  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['eccentricity'] == 0.0004684)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.613  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['epochYear'] == 17)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.613  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$[?(@.['interval'] == 1000)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.613  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['elementNumber'] == 999)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.613  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['rightAscensionAscendingNode'] == 0.6581060650617457)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.614  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['meanAnomaly'] == 5.53182280952528)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.614  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['satelliteClassification'] == 'U')]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.614  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['satelliteNumber'] == 23670)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.619  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$[?(@.['stop'] == '2018-03-09T00:01:39.656Z')]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.620  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['firstDerivativeMeanMotion'] == -5.4E-7)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.620  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['processed'] == true)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.620  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['epochDay'] == 99.51506375)]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.620  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$[?(@.['start'] == '2018-03-09T00:01:32.656Z')]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.620  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['internationalDesignator'] == '95049A  ')]' failed to match document '' because of error 'json string can not be null or empty'
2018-09-13 16:03:53.626  INFO 28416 --- [qtp450309598-28] WireMock : Warning: JSON path expression '$.['elementSet'][?(@.['committed'] == true)]' failed to match document '' because of error 'json string can not be null or empty'

The request is valid json, and the values are correct. Why does this test fail?

marcingrzejszczak commented 6 years ago

That's super interesting... Can you actually make the json smaller and try setting a field after a field to see what's wrong?

E.g. from

{
  "start": "2018-03-09T00:01:32.656Z",
  "stop": "2018-03-09T00:01:39.656Z",
  "interval": 1000,
  "elementSet": {
    "satelliteNumber": 23670,
    "elementNumber": 999,
    "epochYear": 17,
    "revolutionAtEpoch": 7885,
    "epochDay": 99.51506375,
    "firstDerivativeMeanMotion": -5.4E-7,
    "secondDerivativeMeanMotion": 0.0,
    "bstarDragTerm": 0.0,
    "inclination": 0.18693348953485267,
    "rightAscensionAscendingNode": 0.6581060650617457,
    "eccentricity": 4.684E-4,
    "argumentOfPerigee": 4.777837082005226,
    "meanAnomaly": 5.53182280952528,
    "meanMotion": 1.00248515,
    "internationalDesignator": "95049A  ",
    "processed": true,
    "committed": true,
    "satelliteClassification": "U",
    "typeOfEphemeris": "SGP"
  }
}

to

{
  "start": "2018-03-09T00:01:32.656Z",
  "stop": "2018-03-09T00:01:39.656Z",
  "interval": 1000,
  "elementSet": {
    "satelliteNumber": 23670
  }
}
spencergibb commented 6 years ago

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

kpb commented 6 years ago

Is there a way to modify this on the client side? The producer contract is used/shared elsewhere.

The wiremock stub is expecting the complete request and fails with a 404 if I remove parts of it.

@spencergibb, you can close it - but it's a showstopper bug for us. I was trying to be helpful.

marcingrzejszczak commented 6 years ago

I'll look into it.

marcingrzejszczak commented 6 years ago

BTW @kpb have you done what I asked you for?

That's super interesting... Can you actually make the json smaller and try setting a field after a field to see what's wrong?

kpb commented 6 years ago

Yes, but the client test fails when all the fields are not present, so I don't get any useful info.

marcingrzejszczak commented 6 years ago

So only when all fields are present do you get this exception?

kpb commented 6 years ago

I'll run it in a bit with fewer fields and comment with the error.

kpb commented 6 years ago

I don't think running the test with an incomplete request is useful.

When I run the client side test with:

{
  "start": "2018-03-09T00:01:32.656Z"
}

I get:

ServerList:org.springframework.cloud.contract.stubrunner.spring.cloud.ribbon.StubRunnerRibbonServerList@1bea0289
2018-10-02 09:31:42.327  INFO 2598 --- [qtp575309252-27] /                                        : RequestHandlerClass from context returned com.github.tomakehurst.wiremock.http.StubRequestHandler. Normalized mapped under returned 'null'
2018-10-02 09:31:42.413  INFO 2598 --- [qtp575309252-27] WireMock                                 : Warning: JSON path expression '$.['elementSet'][?(@.['typeOfEphemeris'] == 'SGP')]' failed to match document '{"start":"2018-03-09T00:01:32.656Z","stop":null,"interval":0,"elementSet":null}' because of error 'Filter: [?] can not be applied to primitives. Current context is: null'
...
Request was not matched
                                               =======================

-----------------------------------------------------------------------------------------------------------------------
| Closest stub                                             | Request                                                  |
-----------------------------------------------------------------------------------------------------------------------
                                                           |
POST                                                       | POST
/ephemerides                                               | /ephemerides
                                                           |
Content-Type [matches] : application/json.*                | Content-Type: application/json;charset=UTF-8
                                                           |
$.['elementSet'][?(@.['typeOfEphemeris'] == 'SGP')]        | {"start":"2018-03-09T00:01:32.656Z","stop":null,"interval<<<<< Body does not match
marcingrzejszczak commented 6 years ago

I asked you to run the producer side with incomplete results, build a stub and see when it will stop working.

kpb commented 6 years ago

That'll take a while. Another team 'owns' the producer and the stub is pushed to nexus and used by several other projects.

I'll have to set up a project to do this.

marcingrzejszczak commented 6 years ago

Sure, take your time.

Also I wonder if actually the output JSON Path is correct. What if, instead of a text file

{
  "start": "2018-03-09T00:01:32.656Z",
  "stop": "2018-03-09T00:01:39.656Z",
  "interval": 1000,
  "elementSet": {
    "satelliteNumber": 23670,
    "elementNumber": 999,
    "epochYear": 17,
    "revolutionAtEpoch": 7885,
    "epochDay": 99.51506375,
    "firstDerivativeMeanMotion": -5.4E-7,
    "secondDerivativeMeanMotion": 0.0,
    "bstarDragTerm": 0.0,
    "inclination": 0.18693348953485267,
    "rightAscensionAscendingNode": 0.6581060650617457,
    "eccentricity": 4.684E-4,
    "argumentOfPerigee": 4.777837082005226,
    "meanAnomaly": 5.53182280952528,
    "meanMotion": 1.00248515,
    "internationalDesignator": "95049A  ",
    "processed": true,
    "committed": true,
    "satelliteClassification": "U",
    "typeOfEphemeris": "SGP"
  }
}

you will pass a Groovy Map

[
  "start": "2018-03-09T00:01:32.656Z",
  "stop": "2018-03-09T00:01:39.656Z",
  "interval": 1000,
  "elementSet":  [
    "satelliteNumber": 23670,
    "elementNumber": 999,
    "epochYear": 17,
    "revolutionAtEpoch": 7885,
    "epochDay": 99.51506375,
    "firstDerivativeMeanMotion": -5.4E-7,
    "secondDerivativeMeanMotion": 0.0,
    "bstarDragTerm": 0.0,
    "inclination": 0.18693348953485267,
    "rightAscensionAscendingNode": 0.6581060650617457,
    "eccentricity": 4.684E-4,
    "argumentOfPerigee": 4.777837082005226,
    "meanAnomaly": 5.53182280952528,
    "meanMotion": 1.00248515,
    "internationalDesignator": "95049A  ",
    "processed": true,
    "committed": true,
    "satelliteClassification": "U",
    "typeOfEphemeris": "SGP"
  ]
]
spring-projects-issues commented 6 years ago

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

spring-projects-issues commented 6 years ago

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.