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

... #204

Merged
merged 3 commits into from
May 19, 2024
Merged

... #204

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cmd/internal/svc/codegen/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"text/template"
)

Expand Down Expand Up @@ -301,7 +302,7 @@ func InitProj(conf InitProjConfig) {
SvcName string
Version string
}{
DtoPackage: filepath.Join(modName, "dto"),
DtoPackage: strings.ReplaceAll(filepath.Join(modName, "dto"), string(os.PathSeparator), "/"),
SvcName: svcName,
Version: version.Release,
})
Expand Down
4 changes: 3 additions & 1 deletion cmd/internal/svc/codegen/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ func genPlugin(dir string, ic astutils.InterfaceCollector) {
}
defer f.Close()

if tpl, err = template.New(templates.PluginTmpl).Parse(templates.PluginTmpl); err != nil {
funcMap := make(map[string]interface{})
funcMap["toLower"] = strings.ToLower
if tpl, err = template.New(templates.PluginTmpl).Funcs(funcMap).Parse(templates.PluginTmpl); err != nil {
panic(err)
}

Expand Down
6 changes: 1 addition & 5 deletions cmd/internal/svc/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,11 +366,7 @@ func pathsOf(ic astutils.InterfaceCollector, config GenDocConfig) map[string]v3.

var gofileTmpl = `package {{.SvcPackage}}

import "github.com/unionj-cloud/go-doudou/v2/framework/rest"

func init() {
rest.Oas = ` + "`" + `{{.Doc}}` + "`" + `
}
var Oas = ` + "`" + `{{.Doc}}` + "`" + `
`

type GenDocConfig struct {
Expand Down
1 change: 1 addition & 0 deletions cmd/internal/templates/mainmain.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func main() {
go func() {
grpcServer.RunWithPipe(lis)
}()
srv.AddRoutes(rest.DocRoutes(""))
srv.Run()
}
`
4 changes: 3 additions & 1 deletion cmd/internal/templates/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ func (receiver *{{.SvcName}}Plugin) Initialize(restServer *rest.RestServer, grpc
conf := config.LoadFromEnv()
svc := {{.ServiceAlias}}.New{{.SvcName}}(conf)
receiver.serviceInstance = svc
restServer.AddRoute(httpsrv.Routes(httpsrv.New{{.SvcName}}Handler(svc))...)
routes := httpsrv.Routes(httpsrv.New{{.SvcName}}Handler(svc))
restServer.GroupRoutes("/{{.SvcName | toLower}}", routes)
restServer.GroupRoutes("/{{.SvcName | toLower}}", rest.DocRoutes(service.Oas))
if grpcServer.Server == nil {
grpcServer.Server = grpc.NewServer(
grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
Expand Down
71 changes: 65 additions & 6 deletions framework/rest/dochandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,39 @@ package rest

import (
"bytes"
"encoding/json"
"fmt"
"github.com/rs/cors"
"github.com/unionj-cloud/go-doudou/v2/toolkit/stringutils"
"html/template"
"net/http"
"strings"
)

// Oas store OpenAPI3.0 description json string
var Oas string
// window.docs = [
// {
// "label": "Banana",
// "value": "http://localhost:6060/banana/go-doudou/doc",
// },
// {
// "label": "Apple",
// "value": "http://localhost:6060/apple/go-doudou/doc",
// }
//
// ]
var Docs []DocItem
var DocRoutes = docRoutes

func docRoutes() []Route {
return []Route{
type DocItem struct {
Label string `json:"label"`
Value string `json:"value"`
}

func docRoutes(doc string) []Route {
if stringutils.IsEmpty(doc) {
doc = "{}"
}
routes := []Route{
{
Name: "GetDoc",
Method: "GET",
Expand All @@ -25,14 +48,16 @@ func docRoutes() []Route {
if tpl, err = template.New("onlinedoc.tmpl").Parse(onlinedocTmpl); err != nil {
panic(err)
}
doc := Oas
docUrl := "openapi.json"
docs, _ := json.Marshal(Docs)
if err = tpl.Execute(&buf, struct {
Doc string
DocUrl string
Docs string
}{
Doc: doc,
DocUrl: docUrl,
Docs: string(docs),
}); err != nil {
panic(err)
}
Expand All @@ -45,8 +70,42 @@ func docRoutes() []Route {
Method: "GET",
Pattern: "/go-doudou/openapi.json",
HandlerFunc: func(_writer http.ResponseWriter, _req *http.Request) {
_writer.Write([]byte(Oas))
_writer.Write([]byte(doc))
},
},
}
corsOpts := cors.New(cors.Options{
AllowedMethods: []string{
http.MethodGet,
http.MethodPost,
http.MethodPut,
http.MethodPatch,
http.MethodDelete,
http.MethodOptions,
http.MethodHead,
},

AllowedHeaders: []string{
"*",
},

AllowOriginRequestFunc: func(r *http.Request, origin string) bool {
if strings.Contains(r.URL.Path, fmt.Sprintf("%sopenapi.json", gddPathPrefix)) {
return true
}
return false
},
})
gddmiddlewares := []MiddlewareFunc{corsOpts.Handler, MiddlewareFunc(basicAuth())}

for k, item := range routes {
h := http.Handler(item.HandlerFunc)
for i := len(gddmiddlewares) - 1; i >= 0; i-- {
h = gddmiddlewares[i].Middleware(h)
}
item.HandlerFunc = h.(http.HandlerFunc)
routes[k] = item
}

return routes
}
2 changes: 1 addition & 1 deletion framework/rest/docindex.go

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions framework/rest/httprouter/routegroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@ func newRouteGroup(r *Router, path string) *RouteGroup {
}

func (r *RouteGroup) NewGroup(path string) *RouteGroup {
return newRouteGroup(r.r, r.subPath(path))
return newRouteGroup(r.r, r.SubPath(path))
}

func (r *RouteGroup) Handle(method, path string, handle Handle, name ...string) {
r.r.Handle(method, r.subPath(path), handle, name...)
r.r.Handle(method, r.SubPath(path), handle, name...)
}

func (r *RouteGroup) Handler(method, path string, handler http.Handler, name ...string) {
r.r.Handler(method, r.subPath(path), handler, name...)
r.r.Handler(method, r.SubPath(path), handler, name...)
}

func (r *RouteGroup) HandlerFunc(method, path string, handler http.HandlerFunc, name ...string) {
r.r.HandlerFunc(method, r.subPath(path), handler, name...)
r.r.HandlerFunc(method, r.SubPath(path), handler, name...)
}

func (r *RouteGroup) GET(path string, handle Handle) {
Expand All @@ -67,7 +67,7 @@ func (r *RouteGroup) DELETE(path string, handle Handle) {
r.Handle("DELETE", path, handle)
}

func (r *RouteGroup) subPath(path string) string {
func (r *RouteGroup) SubPath(path string) string {
result := r.p + path
if stringutils.IsEmpty(result) {
return "/"
Expand Down
78 changes: 78 additions & 0 deletions framework/rest/lazyregexp/lazyre.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package lazyregexp is a thin wrapper over regexp, allowing the use of global
// regexp variables without forcing them to be compiled at init.
package lazyregexp

import (
"os"
"regexp"
"strings"
"sync"
)

// Regexp is a wrapper around regexp.Regexp, where the underlying regexp will be
// compiled the first time it is needed.
type Regexp struct {
str string
once sync.Once
rx *regexp.Regexp
}

func (r *Regexp) re() *regexp.Regexp {
r.once.Do(r.build)
return r.rx
}

func (r *Regexp) build() {
r.rx = regexp.MustCompile(r.str)
r.str = ""
}

func (r *Regexp) FindSubmatch(s []byte) [][]byte {
return r.re().FindSubmatch(s)
}

func (r *Regexp) FindStringSubmatch(s string) []string {
return r.re().FindStringSubmatch(s)
}

func (r *Regexp) FindStringSubmatchIndex(s string) []int {
return r.re().FindStringSubmatchIndex(s)
}

func (r *Regexp) ReplaceAllString(src, repl string) string {
return r.re().ReplaceAllString(src, repl)
}

func (r *Regexp) FindString(s string) string {
return r.re().FindString(s)
}

func (r *Regexp) FindAllString(s string, n int) []string {
return r.re().FindAllString(s, n)
}

func (r *Regexp) MatchString(s string) bool {
return r.re().MatchString(s)
}

func (r *Regexp) SubexpNames() []string {
return r.re().SubexpNames()
}

var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test")

// New creates a new lazy regexp, delaying the compiling work until it is first
// needed. If the code is being run as part of tests, the regexp compiling will
// happen immediately.
func New(str string) *Regexp {
lr := &Regexp{str: str}
if inTest {
// In tests, always compile the regexps early.
lr.re()
}
return lr
}
Loading
Loading