91 lines
2.5 KiB
Go
91 lines
2.5 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"reflect"
|
|
|
|
"git.loafle.net/loafer/di-go"
|
|
appAnnotation "git.loafle.net/totopia/server/pkg/loafer/app/annotation"
|
|
webAnnotation "git.loafle.net/totopia/server/pkg/loafer/web/annotation"
|
|
"git.loafle.net/totopia/server/pkg/loafer/web/router"
|
|
"github.com/valyala/fasthttp"
|
|
|
|
"github.com/jackc/pgx/v4"
|
|
)
|
|
|
|
type MethodMapping struct {
|
|
Method string
|
|
ParamKeys []string
|
|
}
|
|
|
|
func Run(t reflect.Type) error {
|
|
conn, err := pgx.Connect(context.Background(), fmt.Sprintf("host=%s port=%d user=%s "+
|
|
"password=%s dbname=%s sslmode=disable",
|
|
"localhost", 54320, "totopia", "totopia", "totopia"))
|
|
if err != nil {
|
|
return fmt.Errorf("[%v]", err)
|
|
}
|
|
defer conn.Close(context.Background())
|
|
|
|
di.RegisterResource("dbConn", conn)
|
|
|
|
taServer := di.GetTypeAnnotation(t, appAnnotation.ServerAnnotationType)
|
|
if nil == taServer {
|
|
return fmt.Errorf("[%s] is not Server, use @app:Server", t.Elem().Name())
|
|
|
|
}
|
|
aServer := taServer.(*appAnnotation.ServerAnnotation)
|
|
log.Printf("%s %d", t.Elem().Name(), aServer.HTTPPort)
|
|
|
|
restHandlers, err := di.GetInstancesByAnnotationType(webAnnotation.RestHandlerAnnotationType)
|
|
if nil != err {
|
|
return fmt.Errorf("[%v]", err)
|
|
}
|
|
|
|
r := router.New()
|
|
|
|
for _, restHandler := range restHandlers {
|
|
rha := parseRestHandler(restHandler)
|
|
parseRequestMapping(rha, r, restHandler)
|
|
}
|
|
|
|
if err := fasthttp.ListenAndServe(fmt.Sprintf(":%d", aServer.HTTPPort), r.Handler); nil != err {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func parseRestHandler(restHandler interface{}) *webAnnotation.RestHandlerAnnotation {
|
|
t := reflect.TypeOf(restHandler)
|
|
ta := di.GetTypeAnnotation(t, webAnnotation.RestHandlerAnnotationType)
|
|
if nil == ta {
|
|
log.Printf("Service[%s] is not RESTService, use @RESTService", t.Elem().Name())
|
|
return nil
|
|
}
|
|
return ta.(*webAnnotation.RestHandlerAnnotation)
|
|
}
|
|
|
|
func parseRequestMapping(rha *webAnnotation.RestHandlerAnnotation, r *router.Router, restHandler interface{}) {
|
|
t := reflect.TypeOf(restHandler)
|
|
mas := di.GetMethodAnnotations(t, webAnnotation.RequestMappingAnnotationType)
|
|
if nil == mas || 0 == len(mas) {
|
|
return
|
|
}
|
|
|
|
mf := func(rh interface{}, mn string) fasthttp.RequestHandler {
|
|
return func(ctx *fasthttp.RequestCtx) {
|
|
reflect.ValueOf(rh).MethodByName(mn).Call([]reflect.Value{reflect.ValueOf(ctx)})
|
|
}
|
|
}
|
|
|
|
for methodName, v := range mas {
|
|
ma := v.(*webAnnotation.RequestMappingAnnotation)
|
|
entry := fmt.Sprintf("%s%s", rha.Entry, ma.Entry)
|
|
log.Printf("methodName %s entry %s", methodName, entry)
|
|
r.Handle(ma.Method, entry, mf(restHandler, methodName))
|
|
}
|
|
}
|