// Copyright (c) Shenyang Leading Edge Intelligent Technology Co., Ltd. All rights reserved.
|
|
|
|
package container
|
|
|
|
import (
|
|
"LAPP_GAAS_GFrame_BACKEND/web/models"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/kataras/iris/v12/context"
|
|
"github.com/kataras/iris/v12/core/router"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
ServicesPackageName = "services"
|
|
ServiceNameSuffix = "Service"
|
|
PathSeparator = "/"
|
|
HttpPost HttpMethod = "POST"
|
|
HttpPut HttpMethod = "POU"
|
|
HttpGet HttpMethod = "Get"
|
|
HttpDelete HttpMethod = "DELETE"
|
|
)
|
|
|
|
var ServiceNameSuffixLength = len([]rune(ServiceNameSuffix))
|
|
|
|
type HttpMethod string
|
|
|
|
type (
|
|
// 调用器
|
|
// 参数
|
|
// 1.参数列表
|
|
// 返回值:
|
|
// 1.返回值列表
|
|
Caller = func([]reflect.Value) []reflect.Value
|
|
// 调用器工厂
|
|
// 参数
|
|
// 1.会话标识
|
|
// 2.用户信息
|
|
// 返回值:
|
|
// 1.调用器
|
|
// 2.错误
|
|
CallerFactory = func(string, *models.Usertab) (Caller, error)
|
|
// 路由
|
|
Router = context.Handler
|
|
// 路由创建器
|
|
// 参数
|
|
// 1.会话管理器
|
|
// 2.服务类型
|
|
// 3.服务方法名
|
|
// 3.服务方法类型
|
|
// 返回值:
|
|
// 1.HTTP请求方法
|
|
// 2.附加路径
|
|
// 3.路由
|
|
// 4.错误
|
|
RouterBuilder = func(CallerFactory, string, reflect.Type) (HttpMethod, string, Router, error)
|
|
)
|
|
|
|
// *SessionContext类型常量
|
|
var sessionContextType = reflect.TypeOf((*SessionContext)(nil))
|
|
|
|
// 空参数列表
|
|
var emptyParameters []reflect.Value
|
|
|
|
// Factory零值
|
|
var zeroOfFactory = Factory(reflect.ValueOf(nil))
|
|
|
|
// *error 类型常量
|
|
var errorType = reflect.TypeOf((*error)(nil)).Elem()
|
|
|
|
// *RequestContext类型常量
|
|
var RequestContextType = reflect.TypeOf((*RequestContext)(nil))
|
|
|
|
// 无会话(XORM会话)上下文
|
|
var ContextOfNoSession = NewNoSessionBrokerBuilder()
|
|
|
|
// 新会话(XORM会话)上下文
|
|
var ContextOfNewSession = NewNewSessionBrokerBuilder()
|
|
|
|
// 新事务代理创建器上下文
|
|
var ContextOfNewTransaction = NewNewTransactionBrokerBuilder()
|
|
|
|
//
|
|
//// 组件信息管理器
|
|
//var currentInformationManager = NewInformationManager()
|
|
|
|
// 解析组件工厂,返回:组件工厂Value,组件模块名,组件接口,错误
|
|
// 参数
|
|
// 1.工厂方法
|
|
// 返回值:
|
|
// 1.组件工厂
|
|
// 2.组件接口类型
|
|
// 异常:
|
|
// 1.工厂不能为空
|
|
// 2.工厂必须是func
|
|
// 3.工厂不能有参数
|
|
// 4.工厂必值需有返回值
|
|
// 5.工厂只能有一个返回值
|
|
// 6.工厂的返回值必需是interface
|
|
func parseFactory(factory interface{}) (Factory, Interface) {
|
|
if factory == nil {
|
|
panic(fmt.Sprintf("工厂不能为空!"))
|
|
}
|
|
valueOfFactory := reflect.ValueOf(factory)
|
|
typeOfFactory := valueOfFactory.Type()
|
|
if typeOfFactory.Kind() != reflect.Func {
|
|
panic(fmt.Sprintf("工厂必须是func!"))
|
|
}
|
|
if typeOfFactory.NumIn() != 0 {
|
|
panic(fmt.Sprintf("工厂不能有参数!"))
|
|
}
|
|
if typeOfFactory.NumOut() < 1 {
|
|
panic(fmt.Sprintf("工厂必值需有返回值!"))
|
|
}
|
|
if typeOfFactory.NumOut() > 1 {
|
|
panic(fmt.Sprintf("工厂只能有一个返回值!"))
|
|
}
|
|
if typeOfFactory.Out(0).Kind() != reflect.Interface {
|
|
panic(fmt.Sprintf("工厂的返回值必需是interface!"))
|
|
}
|
|
componentType := typeOfFactory.Out(0)
|
|
return Factory(valueOfFactory), componentType
|
|
}
|
|
|
|
// Caller相等性判断
|
|
// 参数
|
|
// 1.比较对象1
|
|
// 3.比较对象2
|
|
// 返回值:
|
|
// 1.判断结果
|
|
func CallerEqual(caller1 Caller, caller2 Caller) bool {
|
|
if caller1 == nil {
|
|
if caller2 == nil {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
} else {
|
|
if caller2 == nil {
|
|
return false
|
|
} else {
|
|
return reflect.ValueOf(caller1).Pointer() == reflect.ValueOf(caller2).Pointer()
|
|
}
|
|
}
|
|
}
|
|
|
|
var GlobalInformations = NewInformationManager()
|
|
|
|
// 注册路由
|
|
// 参数:
|
|
// 1.路由分组
|
|
// 2.组件信息管理器
|
|
// 3.事务句柄工厂
|
|
// 返回值:
|
|
// 1.错误
|
|
// 异常:
|
|
// 1.组件信息管理器不能为空
|
|
// 2.事务句柄工厂不能为空
|
|
// 3.服务不在包或他的子包之下
|
|
// 4.组件接口名称的后缀不正确
|
|
func RegisterRoutes(party router.Party, defaultRouterBuilder RouterBuilder, informationManager InformationManager, transactionHandlerFactory TransactionHandlerFactory) {
|
|
sessionManager := NewSessionManager(informationManager, transactionHandlerFactory)
|
|
groups := make(map[string][]*ServiceInformation, 10)
|
|
for _, information := range informationManager.Items() {
|
|
if serviceInformation, ok := information.(*ServiceInformation); ok {
|
|
packagePath := serviceInformation.Interface().PkgPath()
|
|
group, ok := groups[packagePath]
|
|
if !ok {
|
|
group = make([]*ServiceInformation, 0, 10)
|
|
}
|
|
groups[packagePath] = append(group, serviceInformation)
|
|
}
|
|
for packagePath, group := range groups {
|
|
packageList := strings.Split(packagePath, PathSeparator)
|
|
moudlePath := ""
|
|
for index, packageName := range packageList {
|
|
if strings.ToLower(packageName) == ServicesPackageName {
|
|
moudlePath = strings.Join(packageList[index+1:], PathSeparator)
|
|
break
|
|
}
|
|
}
|
|
if moudlePath == "" {
|
|
panic(fmt.Sprintf("包%s不在包%s或他的子包之下!", packagePath, ServicesPackageName))
|
|
}
|
|
moudleParty := party.Party(fmt.Sprintf("/%s", strings.ToLower(moudlePath)))
|
|
for _, serviceInformation := range group {
|
|
serviceType := serviceInformation.Interface()
|
|
serviceName := serviceType.Name()
|
|
if !strings.HasSuffix(serviceName, ServiceNameSuffix) {
|
|
panic(fmt.Sprintf("组件%s接口名称的后缀不是%s!", serviceName, ServiceNameSuffix))
|
|
}
|
|
runesOfserviceName := []rune(serviceName)
|
|
serviceParty := moudleParty.Party(fmt.Sprintf("/%s", strings.ToLower(string(runesOfserviceName[:len(runesOfserviceName)-ServiceNameSuffixLength]))))
|
|
for _, serviceMethodInformation := range serviceInformation.Methods() {
|
|
methodName := serviceMethodInformation.MethodName()
|
|
routerBuilder := serviceMethodInformation.RouterBuilder()
|
|
if routerBuilder == nil {
|
|
routerBuilder = defaultRouterBuilder
|
|
}
|
|
|
|
var callerFactory = func(sessionId string, user *models.Usertab) (Caller, error) {
|
|
session, err := sessionManager.GetSession(sessionId, user)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
serviceHandler, ok := session.Handlers().Handler(serviceType).(*ServiceHandler)
|
|
if !ok {
|
|
return nil, errors.New(fmt.Sprintf("竟然没找到服务组件句柄!"))
|
|
}
|
|
return serviceHandler.Method(methodName).Caller(), nil
|
|
}
|
|
|
|
serviceMethodName := fmt.Sprintf("%s.%s", serviceName, methodName)
|
|
httpMethod, addedPath, irisRouter, err := routerBuilder(callerFactory, serviceMethodName, serviceMethodInformation.MethodType())
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
serviceParty.Handle(string(httpMethod), fmt.Sprintf("/%s", strings.ToLower(methodName)+addedPath), irisRouter)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|