pact-foundation / pact-jvm

JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
https://docs.pact.io
Apache License 2.0
1.08k stars 478 forks source link

StreamClosedException when using JerseyProxyClient #620

Open arnzel opened 6 years ago

arnzel commented 6 years ago

I am using the Jersey Proxy client together with the MockServer

    Client client = ClientBuilder.newClient();
    WebTarget webTarget = client.target(mockServer.getUrl());
    RootResource rootResource = WebResourceFactory.newResource(RootResource.class, webTarget);

When i make a call to RootResource like rootResource.doSomeAction(myModelObject) i get

sun.net.httpserver.StreamClosedException: null at sun.net.httpserver.FixedLengthOutputStream.write(FixedLengthOutputStream.java:72) at java.io.FilterOutputStream.write(FilterOutputStream.java:97) at sun.net.httpserver.PlaceholderOutputStream.write(ExchangeImpl.java:439) at au.com.dius.pact.consumer.BaseMockServer.pactResponseToHttpExchange(MockHttpServer.kt:92) at au.com.dius.pact.consumer.BaseMockServer.handle(MockHttpServer.kt:74) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79) at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82) at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:675) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79) at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:647) at sun.net.httpserver.ServerImpl$DefaultExecutor.execute(ServerImpl.java:158) at sun.net.httpserver.ServerImpl$Dispatcher.handle(ServerImpl.java:431) at sun.net.httpserver.ServerImpl$Dispatcher.run(ServerImpl.java:396) at java.lang.Thread.run(Thread.java:748)

uglyog commented 6 years ago

Can you provide the expectations of your test?

uglyog commented 6 years ago

I am unable to replicate this issue, the jersey proxy client seems to work fine for me. Have a look at the test here: https://github.com/DiUS/pact-jvm/blob/master/pact-jvm-consumer/src/test/groovy/au/com/dius/pact/consumer/MockHttpServerSpec.groovy#L50

arnzel commented 6 years ago

Hi, at the moment i have no assertions. The error happens when i add ".willRespondWith().body("responseJsonContent")" where responseContentJson is

{ action: CREATED, createdModels: [ { prop1: "value1", prop2: "value2" } ] }

I create the pact file with

    RequestResponsePact pact = ConsumerPactBuilder.consumer("service2")
            .hasPactWith("service1t")
            .uponReceiving("put model")
            .path("/model")
            .body("requestJsonContent")
            .method("PUT")
            .willRespondWith()
            .status(204)
            .body("responseJsonContent")
            .toPact();

In the logs i see the right response

Generating response: status: 204 ... body: OptionalBody(state=PRESENT, value="responseJsonContent") but then the error occurs

uglyog commented 6 years ago

Ah, I see the issue. You're not creating the JSON body with responseJsonContent, you're creating the body with the string value responseJsonContent, which is not valid JSON. Hence the failure.

You need to remove the qoutes:

RequestResponsePact pact = ConsumerPactBuilder.consumer("service2")
            .hasPactWith("service1t")
            .uponReceiving("put model")
            .path("/model")
            .body("requestJsonContent") // <-- remove the qoutes
            .method("PUT")
            .willRespondWith()
            .status(204)
            .body("responseJsonContent") // <-- remove the qoutes
            .toPact();
arnzel commented 6 years ago

Hi, sorry of course i mean ".body(requestJsonContent)" and body(requestJsonContent). I checked the Json of these Strings and they are valid.

arnzel commented 6 years ago

It also occurs if i put in a minimal valid json like willRespondWith().status(204).body("{}")

uglyog commented 6 years ago

It could be the status code. 204 means no content, so maybe including a body is causing the issue.

Try leave out the .body call on the response.

arnzel commented 6 years ago

Yes this was the mistake. when i change to 200 everything is okay. Thanks !

arnzel commented 6 years ago

Mybe a proper error message would be good