allow to specify external types in ref openapi annotation
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
parent
3e6e9eb469
commit
fc716500c4
2
go.mod
2
go.mod
@ -4,7 +4,7 @@ go 1.16
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/fatih/structtag v1.2.0
|
github.com/fatih/structtag v1.2.0
|
||||||
go.unistack.org/micro-proto/v3 v3.2.3
|
go.unistack.org/micro-proto/v3 v3.2.5
|
||||||
golang.org/x/tools v0.1.9
|
golang.org/x/tools v0.1.9
|
||||||
google.golang.org/protobuf v1.27.1
|
google.golang.org/protobuf v1.27.1
|
||||||
)
|
)
|
||||||
|
4
go.sum
4
go.sum
@ -68,8 +68,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:
|
|||||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||||
go.unistack.org/micro-proto/v3 v3.2.3 h1:vSRI6VoZrlv0pUdo69irHv6HbbnD+oZOGEUE/TS5XBQ=
|
go.unistack.org/micro-proto/v3 v3.2.5 h1:qaMr9oaO8J2X9nvcZfQ+JriuEFfoMzRvFfQdKoVlWgU=
|
||||||
go.unistack.org/micro-proto/v3 v3.2.3/go.mod h1:ZltVWNECD5yK+40+OCONzGw4OtmSdTpVi8/KFgo9dqM=
|
go.unistack.org/micro-proto/v3 v3.2.5/go.mod h1:ZltVWNECD5yK+40+OCONzGw4OtmSdTpVi8/KFgo9dqM=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
100
openapiv3.go
100
openapiv3.go
@ -22,13 +22,14 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"go.unistack.org/micro-proto/v3/api"
|
"go.unistack.org/micro-proto/v3/api"
|
||||||
// v2 "go.unistack.org/micro-proto/v3/openapiv2"
|
|
||||||
v3 "go.unistack.org/micro-proto/v3/openapiv3"
|
v3 "go.unistack.org/micro-proto/v3/openapiv3"
|
||||||
"google.golang.org/protobuf/compiler/protogen"
|
"google.golang.org/protobuf/compiler/protogen"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
"google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
"google.golang.org/protobuf/reflect/protoregistry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -47,6 +48,19 @@ type openapiv3Generator struct {
|
|||||||
namedPathPattern *regexp.Regexp
|
namedPathPattern *regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
once sync.Once
|
||||||
|
protofiles = &protoregistry.Files{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func protofilesAdd(plugin *protogen.Plugin) {
|
||||||
|
for path, f := range plugin.FilesByPath {
|
||||||
|
if _, err := protofiles.FindFileByPath(path); err != nil {
|
||||||
|
protofiles.RegisterFile(f.Desc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// openapiv3Generate creates a new generator for a protoc plugin invocation.
|
// openapiv3Generate creates a new generator for a protoc plugin invocation.
|
||||||
func (g *Generator) openapiv3Generate(component string, plugin *protogen.Plugin) error {
|
func (g *Generator) openapiv3Generate(component string, plugin *protogen.Plugin) error {
|
||||||
og := &openapiv3Generator{
|
og := &openapiv3Generator{
|
||||||
@ -61,6 +75,8 @@ func (g *Generator) openapiv3Generate(component string, plugin *protogen.Plugin)
|
|||||||
namedPathPattern: regexp.MustCompile("{(.+)=(.+)}"),
|
namedPathPattern: regexp.MustCompile("{(.+)=(.+)}"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protofilesAdd(plugin)
|
||||||
|
|
||||||
d := og.buildDocumentV3(plugin)
|
d := og.buildDocumentV3(plugin)
|
||||||
bytes, err := d.YAMLValue("Generated with protoc-gen-go-micro\n")
|
bytes, err := d.YAMLValue("Generated with protoc-gen-go-micro\n")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -245,14 +261,6 @@ func (g *openapiv3Generator) addPathsToDocumentV3(d *v3.Document, file *protogen
|
|||||||
outputMessage := method.Output
|
outputMessage := method.Output
|
||||||
operationID := service.GoName + "_" + method.GoName
|
operationID := service.GoName + "_" + method.GoName
|
||||||
|
|
||||||
/*
|
|
||||||
e2opt := proto.GetExtension(method.Desc.Options(), v2.E_Openapiv2Operation)
|
|
||||||
if e2opt != nil && e2opt != v2.E_Openapiv2Operation.InterfaceOf(v2.E_Openapiv2Operation.Zero()) {
|
|
||||||
if opt, ok := e2opt.(*v2.Operation); ok && opt.OperationId != "" {
|
|
||||||
operationID = opt.OperationId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
e3opt := proto.GetExtension(method.Desc.Options(), v3.E_Openapiv3Operation)
|
e3opt := proto.GetExtension(method.Desc.Options(), v3.E_Openapiv3Operation)
|
||||||
if e3opt != nil && e3opt != v3.E_Openapiv3Operation.InterfaceOf(v3.E_Openapiv3Operation.Zero()) {
|
if e3opt != nil && e3opt != v3.E_Openapiv3Operation.InterfaceOf(v3.E_Openapiv3Operation.Zero()) {
|
||||||
if opt, ok := e3opt.(*v3.Operation); ok && opt.OperationId != "" {
|
if opt, ok := e3opt.(*v3.Operation); ok && opt.OperationId != "" {
|
||||||
@ -640,22 +648,71 @@ func (g *openapiv3Generator) buildOperationV3(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the response.
|
var responses *v3.Responses
|
||||||
responses := &v3.Responses{
|
if eopt != nil && eopt != v3.E_Openapiv3Operation.InterfaceOf(v3.E_Openapiv3Operation.Zero()) {
|
||||||
ResponseOrReference: []*v3.NamedResponseOrReference{
|
opt := eopt.(*v3.Operation)
|
||||||
{
|
if r := opt.Responses; r != nil {
|
||||||
Name: "200",
|
responses = r
|
||||||
Value: &v3.ResponseOrReference{
|
}
|
||||||
Oneof: &v3.ResponseOrReference_Response{
|
|
||||||
Response: &v3.Response{
|
if ref := responses.Default.GetReference(); ref != nil && ref.GetXRef() != "" {
|
||||||
Description: "OK",
|
xref := strings.TrimPrefix(ref.GetXRef(), ".")
|
||||||
Content: g.responseContentForMessage(outputMessage),
|
description := "Default"
|
||||||
},
|
if strings.Contains(xref, "micro.errors.Error") {
|
||||||
|
description += " Error"
|
||||||
|
}
|
||||||
|
desc, err := protofiles.FindDescriptorByName(protoreflect.FullName(xref))
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("unknown ref type %s err %v", xref, err)
|
||||||
|
} else {
|
||||||
|
responses.Default.Oneof = &v3.ResponseOrReference_Response{
|
||||||
|
Response: &v3.Response{
|
||||||
|
Description: description,
|
||||||
|
Content: g.responseContentForMessage(&protogen.Message{
|
||||||
|
Desc: desc.(protoreflect.MessageDescriptor),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, rref := range responses.GetResponseOrReference() {
|
||||||
|
if ref := rref.Value.GetReference(); ref != nil && ref.GetXRef() != "" {
|
||||||
|
xref := strings.TrimPrefix(ref.GetXRef(), ".")
|
||||||
|
description := "Default"
|
||||||
|
if strings.Contains(xref, "micro.errors.Error") {
|
||||||
|
description += " Error"
|
||||||
|
}
|
||||||
|
desc, err := protofiles.FindDescriptorByName(protoreflect.FullName(xref))
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("unknown ref type %s err %v", xref, err)
|
||||||
|
} else {
|
||||||
|
responses.Default.Oneof = &v3.ResponseOrReference_Response{
|
||||||
|
Response: &v3.Response{
|
||||||
|
Description: description,
|
||||||
|
Content: g.responseContentForMessage(&protogen.Message{
|
||||||
|
Desc: desc.(protoreflect.MessageDescriptor),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
responses = &v3.Responses{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the response.
|
||||||
|
responses.ResponseOrReference = append(responses.ResponseOrReference, &v3.NamedResponseOrReference{
|
||||||
|
Name: "200",
|
||||||
|
Value: &v3.ResponseOrReference{
|
||||||
|
Oneof: &v3.ResponseOrReference_Response{
|
||||||
|
Response: &v3.Response{
|
||||||
|
Description: "OK",
|
||||||
|
Content: g.responseContentForMessage(outputMessage),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
|
|
||||||
// Create the operation.
|
// Create the operation.
|
||||||
op := &v3.Operation{
|
op := &v3.Operation{
|
||||||
@ -682,7 +739,6 @@ func (g *openapiv3Generator) buildOperationV3(
|
|||||||
// Pass the entire request message as the request body.
|
// Pass the entire request message as the request body.
|
||||||
typeName := g.fullMessageTypeName(inputMessage.Desc)
|
typeName := g.fullMessageTypeName(inputMessage.Desc)
|
||||||
requestSchema = g.schemaOrReferenceForType(typeName)
|
requestSchema = g.schemaOrReferenceForType(typeName)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// If body refers to a message field, use that type.
|
// If body refers to a message field, use that type.
|
||||||
for _, field := range inputMessage.Fields {
|
for _, field := range inputMessage.Fields {
|
||||||
|
@ -16,8 +16,8 @@ var (
|
|||||||
microServerPackage = protogen.GoImportPath("go.unistack.org/micro/v3/server")
|
microServerPackage = protogen.GoImportPath("go.unistack.org/micro/v3/server")
|
||||||
microClientHttpPackage = protogen.GoImportPath("go.unistack.org/micro-client-http/v3")
|
microClientHttpPackage = protogen.GoImportPath("go.unistack.org/micro-client-http/v3")
|
||||||
microServerHttpPackage = protogen.GoImportPath("go.unistack.org/micro-server-http/v3")
|
microServerHttpPackage = protogen.GoImportPath("go.unistack.org/micro-server-http/v3")
|
||||||
microCodecPackage = protogen.GoImportPath("go.unistack.org/micro/v3/codec")
|
microCodecPackage = protogen.GoImportPath("go.unistack.org/micro-proto/v3/codec")
|
||||||
microErrorsPackage = protogen.GoImportPath("go.unistack.org/micro/v3/errors")
|
microErrorsPackage = protogen.GoImportPath("go.unistack.org/micro-proto/v3/errors")
|
||||||
timePackage = protogen.GoImportPath("time")
|
timePackage = protogen.GoImportPath("time")
|
||||||
deprecationComment = "// Deprecated: Do not use."
|
deprecationComment = "// Deprecated: Do not use."
|
||||||
versionComment = "v3.5.3"
|
versionComment = "v3.5.3"
|
||||||
|
Loading…
Reference in New Issue
Block a user