Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

protoc-gen-swagger: add support for arbitrary extensions #1033

Conversation

srenatus
Copy link
Contributor

@srenatus srenatus commented Sep 5, 2019

Using google.protobuf.Value perhaps isn't the nicest solution here, but with

map<string, google.protobuf.Any> extensions = 15;

I could not find a way to specify those in a_bit_of_everything.proto
that would have passed through protoc.

Instead of

        extensions: {
                key: "x-grpc-gateway-foo"
                value {
                        string_value: "bar"
                }
        }

I have tried

        extensions: {
                key: "x-grpc-gateway-foo"
                value {
                        [type.googleapis.com/google.protobuf.StringValue] {
                                value: "bar"
                        }
                }
         }

following the example of this blog post,
but I've ended up with a protoc call stuck with futex(0x2534960, FUTEX_WAIT_PRIVATE, 2, NULL, see this backtrace: https://gist.github.com/srenatus/ba63e837673a28ba15fcef64cdb6abe0

Also, it's not clear how we'd have truely arbitrary messages, i.e. nothing like google.protobuf.*, resolved there properly....


This is just the first bit -- these extensions go in many places, see https://swagger.io/docs/specification/2-0/swagger-extensions/.

TODO:

  • discuss the overall approach
  • get ordering of extensions to be stable somehow (💭responses does it, too, I believe, and that's also map[string]something)
  • extend the other objects in a similar way
    • toplevel
    • security scheme
    • info
    • paths section, individual
    • paths and operations -- ❔ I think?
    • operation parameters
    • responses
    • tags -- don't seem to be exposed in a way that allows for adding extensions
  • tests

@srenatus srenatus force-pushed the sr/protoc-gen-swagger/support-openapi-v2-extensions branch 2 times, most recently from d3055f2 to 9d5620c Compare September 5, 2019 11:12
Copy link
Collaborator

@johanbrandhorst johanbrandhorst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems reasonable to me, thanks for including an example in a_little_bit_of_everything.proto. I'd like @ivucica's thoughts on this before merging though.

@srenatus
Copy link
Contributor Author

srenatus commented Sep 5, 2019

@johanbrandhorst Ultimately, I want extensions on operations, so if @ivucica agrees with the gist of this, I'd add extensions on the other places where they're valid.

@codecov-io
Copy link

codecov-io commented Sep 5, 2019

Codecov Report

Merging #1033 into master will increase coverage by 0.26%.
The diff coverage is 32.43%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1033      +/-   ##
==========================================
+ Coverage   53.62%   53.89%   +0.26%     
==========================================
  Files          40       40              
  Lines        4052     4125      +73     
==========================================
+ Hits         2173     2223      +50     
+ Misses       1674     1659      -15     
- Partials      205      243      +38
Impacted Files Coverage Δ
protoc-gen-swagger/genswagger/types.go 0% <ø> (ø) ⬆️
protoc-gen-swagger/genswagger/generator.go 10% <0%> (-3.83%) ⬇️
protoc-gen-swagger/genswagger/template.go 56.96% <63.15%> (+2.84%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7f57073...8195bb9. Read the comment docs.

@srenatus
Copy link
Contributor Author

srenatus commented Sep 5, 2019

started with tests. added another TODO (ordering!)

@srenatus srenatus force-pushed the sr/protoc-gen-swagger/support-openapi-v2-extensions branch from f72b737 to dda6116 Compare September 6, 2019 07:16
@srenatus
Copy link
Contributor Author

srenatus commented Sep 7, 2019

generator.go got a little more complicated to cover nested things (security scheme), but it shouldn't get worse for the other parts. I hope. 😄

Using google.protobuf.Value isn't the nicest solution here, but with

    map<string, google.protobuf.Any> extensions = 15;

I could not find a way to specify those in a_bit_of_everything.proto
that would have passed through protoc.

Signed-off-by: Stephan Renatus <srenatus@chef.io>
Signed-off-by: Stephan Renatus <srenatus@chef.io>
Signed-off-by: Stephan Renatus <srenatus@chef.io>
Signed-off-by: Stephan Renatus <srenatus@chef.io>
Signed-off-by: Stephan Renatus <srenatus@chef.io>
@srenatus srenatus force-pushed the sr/protoc-gen-swagger/support-openapi-v2-extensions branch from 791d22a to 712a868 Compare September 8, 2019 11:09
@srenatus
Copy link
Contributor Author

srenatus commented Sep 8, 2019

#!/bin/bash -eo pipefail
git diff --exit-code

with no output, but exit code 1, is a bit mysterious to me 😕

@ivucica
Copy link
Collaborator

ivucica commented Sep 8, 2019

I agree with the switch to google.protobuf.Value, because upon medium-distance inspection, I don't see how to pass a plain string. It looks like types.googleapis.com mechanism only allows specifying proto message types. Perhaps by using types.googleapis.com/google.protobuf.Value with a string value? :)

(Having said this, I think google.protobuf.Any could still be embedded, albeit clumsily (I suppose the value field would have to be the binary-encoded value). Someone did mention using [brackets] to define the type URL, but I can't find this and I don't know how this was meant to be done.)

(Having having said this, yes, google.protobuf.Value is a better option and I like where this is going.)

@ivucica
Copy link
Collaborator

ivucica commented Sep 8, 2019

If you'd like me to take another look, please re-notify me when this is ready for review. Thanks!

@ivucica ivucica removed their request for review September 8, 2019 18:38
Signed-off-by: Stephan Renatus <srenatus@chef.io>
Signed-off-by: Stephan Renatus <srenatus@chef.io>
Signed-off-by: Stephan Renatus <srenatus@chef.io>
Signed-off-by: Stephan Renatus <srenatus@chef.io>
@srenatus
Copy link
Contributor Author

srenatus commented Sep 9, 2019

Sooo.... I've added extension points everywhere I thought they belonged. I'm not 100% certain about the stuff I haven't covered, but I'm also not entire sure about what the OpenAPIv2 docs try to tell me.

I'd be happy if this went in regardless 😅

Also needs squashing, but I kept that for post-review.

@srenatus srenatus marked this pull request as ready for review September 9, 2019 13:04
@srenatus
Copy link
Contributor Author

srenatus commented Sep 9, 2019

Fixing the missing pb.go and the bazel rule.

Signed-off-by: Stephan Renatus <srenatus@chef.io>
Signed-off-by: Stephan Renatus <srenatus@chef.io>
…ment

Dropping the `-` would make `x-foobar` and `x-foo-bar` clash. Replacing
with `_` doesn't.

Signed-off-by: Stephan Renatus <srenatus@chef.io>
Copy link
Collaborator

@johanbrandhorst johanbrandhorst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, @ivucica?

@johanbrandhorst
Copy link
Collaborator

There does seem to be an actual test failure:

 template_test.go:520: applyTemplate(descriptor.File{FileDescriptorProto:(*descriptor.FileDescriptorProto)(0xc00014cb40), GoPkg:descriptor.GoPackage{Path:"example.com/path/to/example/example.pb", Name:"example_pb", Alias:""}, Messages:[]*descriptor.Message{(*descriptor.Message)(0xc0000feaf0)}, Enums:[]*descriptor.Enum(nil), Services:[]*descriptor.Service{(*descriptor.Service)(0xc0000cbe30)}}).response.Extensions = [] want to be [{x-resp-id "resp1000"}]

@srenatus
Copy link
Contributor Author

srenatus commented Sep 9, 2019

Hrm weirdly, those pass locally 😕 I'm looking into it...

@srenatus
Copy link
Contributor Author

srenatus commented Sep 9, 2019

Ah 💡 found the problem, I think. Fixing incoming.

Signed-off-by: Stephan Renatus <srenatus@chef.io>
@johanbrandhorst
Copy link
Collaborator

Thanks, any final thoughts @ivucica?

@srenatus
Copy link
Contributor Author

So, not rushing this, but I've got some time on my hands today, and very little of it in the near future. I'd appreciate another look @ivucica 😉

@ivucica ivucica self-requested a review September 13, 2019 14:29
@ivucica
Copy link
Collaborator

ivucica commented Sep 13, 2019

LG

@johanbrandhorst johanbrandhorst merged commit ffa3b83 into grpc-ecosystem:master Sep 13, 2019
@johanbrandhorst
Copy link
Collaborator

Thanks for your contribution!

@srenatus srenatus deleted the sr/protoc-gen-swagger/support-openapi-v2-extensions branch September 13, 2019 15:03
adasari pushed a commit to adasari/grpc-gateway that referenced this pull request Apr 9, 2020
…tem#1033)

* protoc-gen-swagger: add support for arbitrary top-level extensions

Using google.protobuf.Value isn't the nicest solution here, but with

    map<string, google.protobuf.Any> extensions = 15;

I could not find a way to specify those in a_bit_of_everything.proto
that would have passed through protoc.

Signed-off-by: Stephan Renatus <srenatus@chef.io>

* protoc-gen-swagger: ensure keys start with 'x-'

Signed-off-by: Stephan Renatus <srenatus@chef.io>

* protoc-gen-swagger: start with tests

Signed-off-by: Stephan Renatus <srenatus@chef.io>

* protoc-gen-swagger/genswagger: sort extensions by key, expand test

Signed-off-by: Stephan Renatus <srenatus@chef.io>

* protoc-gen-swagger/genswagger: add custom Extensions to SecurityScheme

Signed-off-by: Stephan Renatus <srenatus@chef.io>

* protoc-gen-swagger/genswagger: add custom Extensions to Info

Signed-off-by: Stephan Renatus <srenatus@chef.io>

* protoc-gen-swagger/genswagger: add custom Extensions to Operation

Signed-off-by: Stephan Renatus <srenatus@chef.io>

* protoc-gen-swagger/genswagger: add custom Extensions to Response

Signed-off-by: Stephan Renatus <srenatus@chef.io>

* protoc-gen-swagger/genswagger: add comment and links

Signed-off-by: Stephan Renatus <srenatus@chef.io>

* update a_bit_of_everything.pb.go

Signed-off-by: Stephan Renatus <srenatus@chef.io>

* update protoc-gen-swagger/genswagger/BUILD.bazel

Signed-off-by: Stephan Renatus <srenatus@chef.io>

* update protoc-gen-swagger/genswagger: fix internal struct key replacement

Dropping the `-` would make `x-foobar` and `x-foo-bar` clash. Replacing
with `_` doesn't.

Signed-off-by: Stephan Renatus <srenatus@chef.io>

* TestApplyTemplateExtensions: fix test

Signed-off-by: Stephan Renatus <srenatus@chef.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants