Compare commits
2 Commits
d35bb7ad5e
...
master
Author | SHA1 | Date | |
---|---|---|---|
c207152892 | |||
|
7a302ce899 |
@@ -7,7 +7,6 @@ import (
|
||||
"os/signal"
|
||||
"time"
|
||||
|
||||
openapi_v3 "github.com/google/gnostic/openapiv3"
|
||||
"github.com/google/uuid"
|
||||
grpccli "go.unistack.org/micro-client-grpc/v3"
|
||||
httpcli "go.unistack.org/micro-client-http/v3"
|
||||
@@ -31,6 +30,7 @@ import (
|
||||
"go.unistack.org/servicechecker/pkg/httpconn"
|
||||
"go.unistack.org/servicechecker/pkg/protoset"
|
||||
"go.unistack.org/servicechecker/pkg/scheduler"
|
||||
"go.unistack.org/servicechecker/pkg/swaggerset"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -213,8 +213,10 @@ func newHTTPTask(ctx context.Context, l logger.Logger, m meter.Meter, check stri
|
||||
var treq client.Request
|
||||
var opts []client.CallOption
|
||||
var labels []string
|
||||
swaggerSet := swaggerset.NewSwaggerSet()
|
||||
|
||||
if task.HTTP.OpenAPI != "" {
|
||||
var svc string
|
||||
|
||||
openapiBuf, err := os.ReadFile(task.HTTP.OpenAPI)
|
||||
if err != nil {
|
||||
@@ -222,12 +224,11 @@ func newHTTPTask(ctx context.Context, l logger.Logger, m meter.Meter, check stri
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
doc, err := openapi_v3.ParseDocument(openapiBuf)
|
||||
err = swaggerSet.AddSwaggerset(task.HTTP.Addr, svc, openapiBuf)
|
||||
if err != nil {
|
||||
l.Error(ctx, "failed to unmarshal openapi file", err)
|
||||
l.Error(ctx, "failed to add openApi spec", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
_ = doc
|
||||
|
||||
errmap := make(map[string]interface{}, 1)
|
||||
errmap["default"] = &codecpb.Frame{}
|
||||
@@ -239,8 +240,17 @@ func newHTTPTask(ctx context.Context, l logger.Logger, m meter.Meter, check stri
|
||||
// client.WithContentType("application/json"),
|
||||
}
|
||||
|
||||
msg, err := swaggerSet.GetMessage(task.HTTP.Addr, svc, task.HTTP.Method)
|
||||
if err != nil {
|
||||
l.Error(ctx, "failed to get message from swagger spec", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req = &codecpb.Frame{Data: []byte(task.HTTP.Data)}
|
||||
rsp = &codecpb.Frame{}
|
||||
if task.HTTP.Data == "" {
|
||||
req = msg.Request
|
||||
}
|
||||
rsp = msg.Response
|
||||
|
||||
treq = c.NewRequest(task.Name, task.Name, req)
|
||||
|
||||
|
5
go.mod
5
go.mod
@@ -4,8 +4,8 @@ go 1.23.3
|
||||
|
||||
require (
|
||||
github.com/go-co-op/gocron/v2 v2.12.3
|
||||
github.com/google/gnostic v0.7.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/ompluscator/dynamic-struct v1.4.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
go.unistack.org/micro-client-grpc/v3 v3.11.10
|
||||
go.unistack.org/micro-client-http/v3 v3.9.14
|
||||
@@ -22,10 +22,13 @@ require (
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/google/gnostic v0.7.0 // indirect
|
||||
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
|
||||
github.com/jonboulle/clockwork v0.4.0 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
github.com/valyala/fastrand v1.1.0 // indirect
|
||||
github.com/valyala/histogram v1.2.0 // indirect
|
||||
go.unistack.org/metrics v0.0.1 // indirect
|
||||
|
8
go.sum
8
go.sum
@@ -805,8 +805,9 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -819,6 +820,8 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
|
||||
github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY=
|
||||
github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE=
|
||||
github.com/ompluscator/dynamic-struct v1.4.0 h1:I/Si9LZtItSwiTMe7vosEuIu2TKdOvWbE3R/lokpN4Q=
|
||||
github.com/ompluscator/dynamic-struct v1.4.0/go.mod h1:ADQ1+6Ox1D+ntuNwTHyl1NvpAqY2lBXPSPbcO4CJdeA=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY=
|
||||
github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
|
||||
@@ -840,8 +843,9 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
|
||||
github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk=
|
||||
github.com/silas/dag v0.0.0-20220518035006-a7e85ada93c5/go.mod h1:7RTUFBdIRC9nZ7/3RyRNH1bdqIShrDejd1YbLwgPS+I=
|
||||
|
81
pkg/swaggerset/swagger.yaml
Normal file
81
pkg/swaggerset/swagger.yaml
Normal file
@@ -0,0 +1,81 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: platform/services/domain/service-proto
|
||||
description: Domain Service
|
||||
version: 3.6.0
|
||||
paths:
|
||||
/domain-service/v1/push_mail/enabled:
|
||||
get:
|
||||
tags:
|
||||
- DomainService
|
||||
description: Получение статуса подключения PUSH (глобального)
|
||||
operationId: IsPushTokenEnabled
|
||||
parameters:
|
||||
- name: Phone
|
||||
in: header
|
||||
schema:
|
||||
type: string
|
||||
- name: app_name
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
- name: device_id.value
|
||||
in: query
|
||||
description: The string value.
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/IsPushTokenEnabledRsp'
|
||||
post:
|
||||
tags:
|
||||
- DomainService
|
||||
description: Сохранение статуса подключения PUSH (глобального)
|
||||
operationId: SetPushTokenEnabled
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SetPushTokenEnabledReq'
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SetPushTokenEnabledRsp'
|
||||
components:
|
||||
schemas:
|
||||
IsPushTokenEnabledRsp:
|
||||
type: object
|
||||
properties:
|
||||
result:
|
||||
type: boolean
|
||||
setPushTokenEnabledRsp:
|
||||
$ref: '#/components/schemas/SetPushTokenEnabledRsp'
|
||||
SetPushTokenEnabledReq:
|
||||
type: object
|
||||
properties:
|
||||
app_name:
|
||||
type: string
|
||||
enabled:
|
||||
type: boolean
|
||||
device_id:
|
||||
$ref: '#/components/schemas/StringValue'
|
||||
StringValue:
|
||||
type: object
|
||||
properties:
|
||||
value:
|
||||
type: string
|
||||
description: The string value.
|
||||
description: Wrapper message for `string`. The JSON representation for `StringValue` is JSON string.
|
||||
SetPushTokenEnabledRsp:
|
||||
type: object
|
||||
properties:
|
||||
result:
|
||||
type: boolean
|
82
pkg/swaggerset/swaggerset.go
Normal file
82
pkg/swaggerset/swaggerset.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package swaggerset
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
openapi "go.unistack.org/micro-proto/v3/openapiv3"
|
||||
)
|
||||
|
||||
var errNotFound = errors.New("file descriptor not found")
|
||||
|
||||
type SwaggerSet struct {
|
||||
mu sync.Mutex
|
||||
files map[string]*openapi.Document
|
||||
}
|
||||
|
||||
func NewSwaggerSet() *SwaggerSet {
|
||||
return &SwaggerSet{
|
||||
mu: sync.Mutex{},
|
||||
files: make(map[string]*openapi.Document, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *SwaggerSet) GetMessage(addr, svc, mth string) (*Message, error) {
|
||||
if svc == "" || mth == "" || addr == "" {
|
||||
return nil, errors.New("addr or service name is empty")
|
||||
}
|
||||
|
||||
p.mu.Lock()
|
||||
doc := p.files[addr+"|"+svc]
|
||||
p.mu.Unlock()
|
||||
|
||||
var reqParam, reqBody, rsp interface{}
|
||||
var typeReq string
|
||||
for _, path := range doc.Paths.GetPath() {
|
||||
if path.GetName() == mth {
|
||||
if path.GetValue().GetGet() != nil {
|
||||
typeReq = http.MethodGet
|
||||
reqParam, reqBody, rsp = handleOperation(path.GetValue().GetGet(), doc)
|
||||
}
|
||||
if path.GetValue().GetPost() != nil {
|
||||
typeReq = http.MethodPost
|
||||
reqParam, reqBody, rsp = handleOperation(path.GetValue().GetPost(), doc)
|
||||
}
|
||||
if path.GetValue().GetDelete() != nil {
|
||||
typeReq = http.MethodDelete
|
||||
reqParam, reqBody, rsp = handleOperation(path.GetValue().GetDelete(), doc)
|
||||
}
|
||||
if path.GetValue().GetPatch() != nil {
|
||||
typeReq = http.MethodPatch
|
||||
reqParam, reqBody, rsp = handleOperation(path.GetValue().GetPatch(), doc)
|
||||
}
|
||||
if path.GetValue().GetPut() != nil {
|
||||
typeReq = http.MethodPut
|
||||
reqParam, reqBody, rsp = handleOperation(path.GetValue().GetPut(), doc)
|
||||
}
|
||||
}
|
||||
}
|
||||
msg := &Message{
|
||||
Type: typeReq,
|
||||
Request: httpRequest{
|
||||
Header: reqParam,
|
||||
Body: reqBody,
|
||||
},
|
||||
Response: rsp,
|
||||
}
|
||||
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
func (p *SwaggerSet) AddSwaggerset(addr, svc string, data []byte) error {
|
||||
doc, err := openapi.ParseDocument(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.mu.Lock()
|
||||
p.files[addr+"|"+svc] = doc
|
||||
p.mu.Unlock()
|
||||
return nil
|
||||
}
|
33
pkg/swaggerset/swaggerset_test.go
Normal file
33
pkg/swaggerset/swaggerset_test.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package swaggerset
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSwaggerSet_1(t *testing.T) {
|
||||
s := NewSwaggerSet()
|
||||
data, err := os.ReadFile("swagger.yaml")
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = s.AddSwaggerset("localhost:8080", "service", data)
|
||||
assert.Nil(t, err)
|
||||
|
||||
msg, err := s.GetMessage(
|
||||
"localhost:8080",
|
||||
"service",
|
||||
"/domain-service/v1/push_mail/enabled",
|
||||
"GET")
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, msg)
|
||||
req, err := json.Marshal(msg.Request)
|
||||
assert.Nil(t, err)
|
||||
rsp, err := json.Marshal(msg.Response)
|
||||
assert.Nil(t, err)
|
||||
fmt.Printf("JSON: type: %s, req: %s, rsp: %s \n", msg.Type, req, rsp)
|
||||
fmt.Printf("Struct: type: %s, req: %+v, rsp: %+v \n", msg.Type, msg.Request, msg.Response)
|
||||
}
|
189
pkg/swaggerset/util.go
Normal file
189
pkg/swaggerset/util.go
Normal file
@@ -0,0 +1,189 @@
|
||||
package swaggerset
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
dynamicstruct "github.com/ompluscator/dynamic-struct"
|
||||
openapi "go.unistack.org/micro-proto/v3/openapiv3"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
Type string
|
||||
Request httpRequest
|
||||
Response interface{}
|
||||
}
|
||||
|
||||
type httpRequest struct {
|
||||
Header interface{}
|
||||
Body interface{}
|
||||
}
|
||||
|
||||
func handleOperation(operation *openapi.Operation, doc *openapi.Document) (reqParam, reqBody, rsp interface{}) {
|
||||
// Обработка параметров (GET)
|
||||
if len(operation.Parameters) > 0 {
|
||||
paramsStruct := dynamicstruct.NewStruct()
|
||||
for _, paramRef := range operation.Parameters {
|
||||
var param *openapi.Parameter
|
||||
param = paramRef.GetParameter()
|
||||
fieldName := capitalize(param.Name)
|
||||
jsonName := strings.ToLower(param.Name[:1]) + param.Name[1:]
|
||||
goType := getGoType(doc, param.Schema)
|
||||
|
||||
// В зависимости от того, где параметр находится (header, query, path, etc.), добавляем соответствующий тег
|
||||
switch param.In {
|
||||
case "query":
|
||||
paramsStruct = paramsStruct.AddField(fieldName, goType, fmt.Sprintf(`json:"%s" query:"%s"`, jsonName, jsonName))
|
||||
case "header":
|
||||
paramsStruct = paramsStruct.AddField(fieldName, goType, fmt.Sprintf(`json:"%s" header:"%s"`, jsonName, jsonName))
|
||||
default:
|
||||
paramsStruct = paramsStruct.AddField(fieldName, goType, fmt.Sprintf(`json:"%s"`, jsonName))
|
||||
}
|
||||
}
|
||||
// Получили структуру запроса для методов, где есть параметры в header, query, path, etc., добавили теги
|
||||
reqParam = paramsStruct.Build().New()
|
||||
}
|
||||
|
||||
// Обработка тела запроса (POST)
|
||||
if operation.GetRequestBody() != nil {
|
||||
if operation.GetRequestBody().GetRequestBody() != nil {
|
||||
bodyFields := buildDynamicStruct(doc, operation.GetRequestBody().GetRequestBody().GetContent().GetAdditionalProperties()[0].GetValue().GetSchema())
|
||||
bodyStruct := reflect.StructOf(bodyFields)
|
||||
bodyInstance := reflect.New(bodyStruct).Interface()
|
||||
// Получили тело запроса
|
||||
reqBody = bodyInstance
|
||||
}
|
||||
if operation.GetRequestBody().GetReference() != nil {
|
||||
schemOrRef := findReference(doc, operation.GetRequestBody().GetReference().GetXRef())
|
||||
bodyFields := buildDynamicStruct(doc, schemOrRef)
|
||||
bodyStruct := reflect.StructOf(bodyFields)
|
||||
bodyInstance := reflect.New(bodyStruct).Interface()
|
||||
// Получили тело запроса
|
||||
reqBody = bodyInstance
|
||||
}
|
||||
}
|
||||
|
||||
// Обработка ответов
|
||||
for _, rspOrRef := range operation.Responses.ResponseOrReference {
|
||||
if rspOrRef.GetValue().GetResponse() != nil {
|
||||
for _, prop := range rspOrRef.Value.GetResponse().GetContent().GetAdditionalProperties() {
|
||||
responseFields := buildDynamicStruct(doc, prop.GetValue().GetSchema())
|
||||
responseStruct := reflect.StructOf(responseFields)
|
||||
responseInstance := reflect.New(responseStruct).Interface()
|
||||
// Получили структуру ответа
|
||||
rsp = responseInstance
|
||||
}
|
||||
}
|
||||
if rspOrRef.GetValue().GetReference() != nil {
|
||||
schemaOrRef := findReference(doc, rspOrRef.GetValue().GetReference().GetXRef())
|
||||
responseFields := buildDynamicStruct(doc, schemaOrRef)
|
||||
responseStruct := reflect.StructOf(responseFields)
|
||||
responseInstance := reflect.New(responseStruct).Interface()
|
||||
// Получили структуру ответа
|
||||
rsp = responseInstance
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Рекурсивное создание структуры из схемы с учетом $ref
|
||||
func buildDynamicStruct(doc *openapi.Document, schemaOrRef *openapi.SchemaOrReference) []reflect.StructField {
|
||||
var sfields []reflect.StructField
|
||||
var schema *openapi.Schema
|
||||
if schemaOrRef.GetSchema() != nil {
|
||||
schema = schemaOrRef.GetSchema()
|
||||
}
|
||||
if schemaOrRef.GetReference() != nil {
|
||||
name := strings.Split(schemaOrRef.GetReference().GetXRef(), "#/components/schemas/")[1]
|
||||
fieldName := capitalize(name)
|
||||
subBuilder := buildDynamicStruct(doc, findReference(doc, schemaOrRef.GetReference().GetXRef()))
|
||||
sfield := reflect.StructField{
|
||||
Name: fieldName,
|
||||
Type: reflect.StructOf(subBuilder),
|
||||
Tag: reflect.StructTag(fmt.Sprintf(`json:"%s"`, name)),
|
||||
}
|
||||
sfields = append(sfields, sfield)
|
||||
}
|
||||
|
||||
for _, prop := range schema.GetProperties().GetAdditionalProperties() {
|
||||
fieldName := capitalize(prop.GetName())
|
||||
if prop.GetValue().GetReference() != nil {
|
||||
subBuilder := buildDynamicStruct(doc, prop.GetValue())
|
||||
|
||||
sfield := reflect.StructField{
|
||||
Name: fieldName,
|
||||
Type: reflect.StructOf(subBuilder),
|
||||
Tag: reflect.StructTag(fmt.Sprintf(`json:"%s"`, prop.GetName())),
|
||||
}
|
||||
|
||||
sfields = append(sfields, sfield)
|
||||
}
|
||||
if prop.GetValue().GetSchema() != nil {
|
||||
sfield := reflect.StructField{
|
||||
Name: fieldName,
|
||||
Type: reflect.TypeOf(getGoType(doc, prop.GetValue())),
|
||||
Tag: reflect.StructTag(fmt.Sprintf(`json:"%s"`, prop.GetName())),
|
||||
}
|
||||
|
||||
sfields = append(sfields, sfield)
|
||||
}
|
||||
}
|
||||
|
||||
return sfields
|
||||
}
|
||||
|
||||
func findReference(doc *openapi.Document, ref string) *openapi.SchemaOrReference {
|
||||
var result *openapi.SchemaOrReference
|
||||
ref = strings.Split(ref, "#/components/schemas/")[1]
|
||||
|
||||
for _, prop := range doc.Components.Schemas.GetAdditionalProperties() {
|
||||
if prop.Name == ref {
|
||||
result = prop.Value
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Преобразование типа OpenAPI в тип Go
|
||||
func getGoType(doc *openapi.Document, schema *openapi.SchemaOrReference) interface{} {
|
||||
switch schema.GetSchema().Type {
|
||||
case "string":
|
||||
return ""
|
||||
case "integer":
|
||||
return 0
|
||||
case "boolean":
|
||||
return false
|
||||
case "array":
|
||||
return []interface{}{}
|
||||
case "object":
|
||||
return buildDynamicStruct(doc, schema)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func capitalize(fieldName string) string {
|
||||
if fieldName == "" {
|
||||
return fieldName
|
||||
}
|
||||
// Заменяем точки на подчеркивания для унификации
|
||||
fieldName = strings.ReplaceAll(fieldName, ".", "_")
|
||||
|
||||
// Разделяем строку по подчеркиваниям
|
||||
parts := strings.Split(fieldName, "_")
|
||||
if len(parts) == 1 {
|
||||
return strings.ToUpper(fieldName[:1]) + fieldName[1:]
|
||||
}
|
||||
|
||||
// Обрабатываем каждый фрагмент
|
||||
for i := 0; i < len(parts); i++ {
|
||||
// Капитализируем первые буквы всех частей, кроме первой
|
||||
parts[i] = strings.Title(parts[i]) // cases.Title(language.English).String(parts[i])
|
||||
}
|
||||
|
||||
// Собираем строку обратно, соединяя части без подчеркиваний
|
||||
return strings.Join(parts, "")
|
||||
}
|
Reference in New Issue
Block a user