testinggospels / camouflage

Camouflage is a backend mocking tool for HTTP, gRPC, Websockets and Thrift protocols, which helps you carry out your front end prototyping, unit testing, functional/performance testing in silos, in absence of one or more Microservices/APIs.
https://testinggospels.github.io/camouflage/
MIT License
270 stars 26 forks source link

GRPC: service doesn't start if proto custom options present #186

Closed avarabyeu closed 2 years ago

avarabyeu commented 2 years ago

Describe the bug GRPC service is ignored in case custom (e.g. grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) proto option is defined in the proto definition. If custom option is commented out, camouflage starts the service properly and works as expected

To Reproduce Steps to reproduce the behavior:

  1. Proto example (
    
    syntax = "proto3";
    package action_executor.v1;

import "google/protobuf/empty.proto"; import "google/api/annotations.proto"; import "protoc-gen-openapiv2/options/annotations.proto";

service ActionExecutor { // DE Engine service implementation rpc Execute(ExecuteRequest) returns (ExecuteResponse) { option (google.api.http) = { post: "/v2/execute" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { description: "Executes an action"; summary: "Executes an action"; }; } rpc GetSupportedActions(google.protobuf.Empty) returns (GetSupportedActionsResponse) { option (google.api.http) = { get: "/v2/actions" }; };

}

message GetSupportedActionsResponse { repeated string actions = 1; }

message ExecuteRequest { messages.v1.Session session = 1; string action_id = 2 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { title: "ID of action to be executed", description: "ID of action to be executed" }]; }

message ExecuteResponse { oneof payload { google.protobuf.Empty empty = 1; ActivityReply reply = 2; } } message ActivityReply { string session_id = 1; } ...

2. Folder Structure 

├── mocks │   ├── camouflage.log │   ├── config.yml │   ├── grpc │   │   ├── mocks │   │   │   ├── action_executor │   │   │   │   └── v1 │   │   │   │   └── ActionExecutor │   │   │   │   ├── Execute.mock │   │   │   │   └── GetSupportedActions.mock │   │   └── protos │   │   └── all.proto │   └── plconfig.js └── third-party └── protoc-gen-openapiv2 └── options ├── annotations.proto └── openapiv2.proto


plconfig.js file content:
```js
module.exports.plconfig = {
    keepCase: false,
    includeDirs: [
        "./grpc/protos",
        "./../third-party",
    ]
}
  1. Error Stack Trace Error: illegal name ';' (action_executor.proto, line 18)

Expected behavior Files from all includeDirs are loaded properly, custom proto options are recognized

Desktop (please complete the following information):

Additional context

2022-08-30 15:46:25 info: [19924] Master Started 
2022-08-30 15:46:25 info: Cluster metrics server listening to 5555, metrics exposed on http://localhost:5555/metrics . Set a negative value for config.monitoring.port to enable monitoring  
2022-08-30 15:46:26 debug: {
  "loglevel": "debug",
  "cpus": 1,
  "monitoring": {
    "port": 5555
  },
  "protocols": {
    "grpc": {
      "enable": true,
      "host": "0.0.0.0",
      "port": 4312,
      "mocks_dir": "./grpc/mocks",
      "protos_dir": "./grpc/protos",
      "grpc_tls": false
    },
    "http": {
      "enable": true,
      "mocks_dir": "./mocks",
      "port": 8080
    },
    "https": {
      "enable": false,
      "port": 8443
    },
    "http2": {
      "enable": false,
      "port": 8081
    },
    "ws": {
      "enable": false,
      "port": 8082,
      "mocks_dir": "./ws_mocks"
    },
    "thrift": {
      "enable": false,
      "mocks_dir": "./thrift/mocks",
      "services": []
    }
  },
  "ssl": {
    "cert": null,
    "key": null,
    "root_cert": null
  },
  "backup": {
    "enable": false,
    "cron": "0 * * * *"
  },
  "cache": {
    "enable": false,
    "ttl_seconds": 300
  },
  "injection": {
    "enable": false
  },
  "ext_helpers": null,
  "origins": []
} 
2022-08-30 15:46:26 info: [19928] Worker started 
2022-08-30 15:46:26 info: Handlebar helpers registration started 
2022-08-30 15:46:26 warn: Code Injection is disabled. Helpers such as code, inject, pg, csv and functionalities such as external helpers, will not work. 
2022-08-30 15:46:26 info: Handlebar helpers registration completed 
2022-08-30 15:46:26 debug: Found protofile: all.proto 
2022-08-30 15:46:26 debug: Using proto-loader config as: {"keepCase":false,"includeDirs":["./grpc/protos","./../proto","./../third-party"]} 
2022-08-30 15:46:26 debug: Ignoring protofiles:  
2022-08-30 15:46:26 debug: Using insecure gRPC server credentials. 
2022-08-30 15:46:26 debug: Registering Unary method: Handle 
2022-08-30 15:46:26 debug: Registering Unary method: Reply 
2022-08-30 15:46:26 info: No middleware injection. 
2022-08-30 15:46:26 info: Worker sharing HTTP server at http://localhost:8080 ⛳ 
2022-08-30 15:46:26 info: Worker sharing gRPC server at 0.0.0.0:4312 ⛳ 
shubhendumadhukar commented 2 years ago

Hi @avarabyeu,

In the directory structure, you have provided, I don't see a file action_executor.proto. However, the error message refers to that file. Error: illegal name ';' (action_executor.proto, line 18). I am assuming all.proto and action_executor.proto are the same files.

I tried replicating the issue using the @grpc/proto-loader, and I am assuming the issue is with following section of the proto file

option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      description: "Executes an action";
      summary: "Executes an action";
    };

Could you please confirm if removing the semicolons works for you?

avarabyeu commented 2 years ago

thanks, it helps!