Search code examples
javaspring-bootgrpc-javawiremockwiremock-standalone

Wiremock GRPC demo example is not returning response


I am trying to run the demo provided at wiremock grpc page using spring boot: https://wiremock.org/docs/grpc/

I have the following configuration for the beans:

@Configuration
public class WiremockConfiguration {

@Bean
public WireMockServer grpcWireMockServer() {
    var server = startGrpcWiremockServer();

    return server;
}

@Bean
public WireMockGrpcService marginReportHistoryServiceGrpc(@Qualifier("grpcWireMockServer") WireMockServer grpcWireMockServer) {
    var mockService = new WireMockGrpcService(new WireMock(grpcWireMockServer.port()), "com.example.grpc.GreetingService");

    System.out.println("Port: " + grpcWireMockServer.port());

    mockService.stubFor(
            method("/greeting")
                    .withRequestMessage(equalToJson("{ \"name\":  \"Tom\" }"))
                    .willReturn(json("{ \"greeting\": \"Hi Tom from JSON\" }"))
    );

    return mockService;
}

public WireMockServer startGrpcWiremockServer() {
    var server = new WireMockServer(wireMockConfig()
            .dynamicPort()
            .withRootDirectory("src/main/resources/wiremock")
            .extensions(new GrpcExtensionFactory())
    );

    server.start();

    return server;
}
}

Full code can be found here: https://github.com/gasparuhov-dev/wiremock-grpc

After I start the service, port is loged, and when I try to call the wiremock, using postman I recive Internal error:

enter image description here

Any ideas what am I missing?


Solution

  • Many thanks for providing a demo project. It helps to understand what is going on.

    From what I can tell, this could be a combination of things. Firstly, you shouldn't need the / on the front of the /greeting method. So, update:

        mockService.stubFor(
                method("/greeting")
                        .withRequestMessage(equalToJson("{ \"name\":  \"Tom\" }"))
                        .willReturn(json("{ \"greeting\": \"Hi Tom from JSON\" }"))
        );
    

    To this:

        mockService.stubFor(
                method("greeting")
                        .withRequestMessage(equalToJson("{ \"name\":  \"Tom\" }"))
                        .willReturn(json("{ \"greeting\": \"Hi Tom from JSON\" }"))
        );
    

    Next I think you have a mismatch of dependencies. You are using the standalone version of WireMock but not the standalone version of the gRPC extension:

            <dependency>
                <groupId>org.wiremock</groupId>
                <artifactId>wiremock-standalone</artifactId>
                <version>3.10.0</version>
            </dependency>
            <dependency>
                <groupId>org.wiremock</groupId>
                <artifactId>wiremock-grpc-extension</artifactId>
                <version>0.9.0</version>
            </dependency>
    

    If you update the gRPC extension to use the standalone version as well that should hopefully get things up and running for you:

            <dependency>
                <groupId>org.wiremock</groupId>
                <artifactId>wiremock-grpc-extension-standalone</artifactId>
                <version>0.9.0</version>
            </dependency>
    

    You should be able to use all the jetty12 version of the dependencies given you are using 3.x.x version of Spring Boot so that might be worth looking into as well. You can see those dependencies in the demo project here - https://github.com/wiremock/wiremock-grpc-demos/blob/main/java-jetty12/build.gradle#L45

    When I start your demo app I get the port printed to the console as you mentioned:

    Port: 49367
    

    I can then send a request to the server using grpcurl:

    grpcurl -v -plaintext -d '{"name": "Tom"}' localhost:49367 com.example.grpc.GreetingService/greeting
    
    Resolved method descriptor:
    rpc greeting ( .com.example.grpc.HelloRequest ) returns ( .com.example.grpc.HelloResponse );
    
    Request metadata to send:
    (empty)
    
    Response headers received:
    content-type: application/grpc
    grpc-accept-encoding: gzip
    
    Response contents:
    {
      "greeting": "Hi Tom from JSON"
    }
    
    Response trailers received:
    (empty)
    Sent 1 request and received 1 response