Skip to content

Commit

Permalink
[add] studio api server
Browse files Browse the repository at this point in the history
  • Loading branch information
trheyi committed Oct 13, 2022
1 parent 3f0869c commit d74f74b
Show file tree
Hide file tree
Showing 7 changed files with 511 additions and 20 deletions.
34 changes: 20 additions & 14 deletions config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,26 @@ package config

// Config 象传应用引擎配置
type Config struct {
Mode string `json:"mode,omitempty" env:"YAO_ENV" envDefault:"production"` // 象传引擎启动模式 production/development
Root string `json:"root,omitempty" env:"YAO_ROOT" envDefault:"."` // 应用根目录
DataRoot string `json:"data_root,omitempty" env:"YAO_DATA_ROOT" envDefault:""` // DATA PATH
Host string `json:"host,omitempty" env:"YAO_HOST" envDefault:"0.0.0.0"` // 服务监听地址
Port int `json:"port,omitempty" env:"YAO_PORT" envDefault:"5099"` // 服务监听端口
Cert string `json:"cert,omitempty" env:"YAO_CERT"` // HTTPS 证书文件地址
Key string `json:"key,omitempty" env:"YAO_KEY"` // HTTPS 证书密钥地址
Log string `json:"log,omitempty" env:"YAO_LOG"` // 服务日志地址
LogMode string `json:"log_mode,omitempty" env:"YAO_LOG_MODE" envDefault:"TEXT"` // 服务日志模式 JSON|TEXT
// Session string `json:"session,omitempty" env:"YAO_SESSION" envDefault:"memory"` // 用户会话模式 memory|redis|database
JWTSecret string `json:"jwt_secret,omitempty" env:"YAO_JWT_SECRET"` // JWT 密钥
DB DBConfig `json:"db,omitempty"` // 数据库配置
AllowFrom []string `json:"allowfrom,omitempty" envSeparator:"|" env:"YAO_ALLOW_FROM" ` // Domain list the separator is |
Session SessionConfig `json:"session,omitempty"`
Mode string `json:"mode,omitempty" env:"YAO_ENV" envDefault:"production"` // 象传引擎启动模式 production/development
Root string `json:"root,omitempty" env:"YAO_ROOT" envDefault:"."` // 应用根目录
DataRoot string `json:"data_root,omitempty" env:"YAO_DATA_ROOT" envDefault:""` // DATA PATH
Host string `json:"host,omitempty" env:"YAO_HOST" envDefault:"0.0.0.0"` // 服务监听地址
Port int `json:"port,omitempty" env:"YAO_PORT" envDefault:"5099"` // 服务监听端口
Cert string `json:"cert,omitempty" env:"YAO_CERT"` // HTTPS 证书文件地址
Key string `json:"key,omitempty" env:"YAO_KEY"` // HTTPS 证书密钥地址
Log string `json:"log,omitempty" env:"YAO_LOG"` // 服务日志地址
LogMode string `json:"log_mode,omitempty" env:"YAO_LOG_MODE" envDefault:"TEXT"` // 服务日志模式 JSON|TEXT
JWTSecret string `json:"jwt_secret,omitempty" env:"YAO_JWT_SECRET"` // JWT 密钥
DB DBConfig `json:"db,omitempty"` // 数据库配置
AllowFrom []string `json:"allowfrom,omitempty" envSeparator:"|" env:"YAO_ALLOW_FROM"` // Domain list the separator is |
Session SessionConfig `json:"session,omitempty"` // Session Config
Studio StudioConfig `json:"studio,omitempty"` // Studio config
}

// StudioConfig the studio config
type StudioConfig struct {
Port int `json:"studio_port,omitempty" env:"YAO_STUDIO_PORT" envDefault:"5077"` // Studio port
Secret int `json:"studio_secret,omitempty" env:"YAO_STUDIO_SECRET"` // Studio Secret, if does not set, auto-generate a secret
}

// DBConfig 数据库配置
Expand Down
41 changes: 41 additions & 0 deletions studio/middleware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package studio

import (
"fmt"
"net/http"

"github.com/gin-gonic/gin"
"github.com/yaoapp/kun/exception"
"github.com/yaoapp/xun"
)

func hdRecovered(c *gin.Context, recovered interface{}) {

var code = http.StatusInternalServerError

if err, ok := recovered.(string); ok {
c.JSON(code, xun.R{
"code": code,
"message": fmt.Sprintf("%s", err),
})
} else if err, ok := recovered.(exception.Exception); ok {
code = err.Code
c.JSON(code, xun.R{
"code": code,
"message": err.Message,
})
} else if err, ok := recovered.(*exception.Exception); ok {
code = err.Code
c.JSON(code, xun.R{
"code": code,
"message": err.Message,
})
} else {
c.JSON(code, xun.R{
"code": code,
"message": fmt.Sprintf("%v", recovered),
})
}

c.AbortWithStatus(code)
}
183 changes: 183 additions & 0 deletions studio/router.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
package studio

import (
"fmt"
"io"
"os"
"strings"

"github.com/gin-gonic/gin"
jsoniter "github.com/json-iterator/go"
"github.com/yaoapp/gou"
)

// Serve start the api server
func setRouter(router *gin.Engine) {

router.Use(gin.CustomRecovery(hdRecovered))

// DSL ReadDir, ReadFile
router.GET("/dsl/:method", func(c *gin.Context) {
method := strings.ToLower(c.Param("method"))
switch method {

case "readfile":
name := c.Query("name")
if name == "" {
throw(c, 400, "file name is required")
return
}

data, err := dfs.ReadFile(name)
if err != nil {
throw(c, 500, err.Error())
return
}

res := map[string]interface{}{}
err = jsoniter.Unmarshal(data, &res)
if err != nil {
throw(c, 500, err.Error())
return
}
c.JSON(200, res)
c.Done()
break

case "readdir":
name := c.Query("name")
if name == "" {
throw(c, 400, "dir name is required")
return
}

recursive := false
if c.Query("recursive") == "1" || strings.ToLower(c.Query("recursive")) == "true" {
recursive = true
}
data, err := dfs.ReadDir(name, recursive)
if err != nil {
throw(c, 500, err.Error())
return
}
c.JSON(200, data)
c.Done()
break
}
})

// DSL WriteFile, Mkdir, MkdirAll ...
router.POST("/dsl/:method", func(c *gin.Context) {

method := strings.ToLower(c.Param("method"))
switch method {
case "writefile":
name := c.Query("name")
if name == "" {
throw(c, 400, "dir name is required")
return
}

payload, err := io.ReadAll(c.Request.Body)
if err != nil {
throw(c, 500, err.Error())
return
}

if payload == nil || len(payload) == 0 {
throw(c, 500, "file content is required")
return
}

length, err := dfs.WriteFile(name, payload, 0644)
if err != nil {
throw(c, 500, err.Error())
return
}

c.JSON(200, length)
c.Done()
break

case "mkdir":
name := c.Query("name")
if name == "" {
throw(c, 400, "dir name is required")
return
}

err := dfs.Mkdir(name, int(os.ModePerm))
if err != nil {
throw(c, 500, err.Error())
return
}
c.Status(200)
c.Done()
break

case "mkdirall":
name := c.Query("name")
if name == "" {
throw(c, 400, "dir name is required")
return
}

err := dfs.MkdirAll(name, int(os.ModePerm))
if err != nil {
throw(c, 500, err.Error())
return
}
c.Status(200)
c.Done()
break
}

})

// Cloud Functions
router.POST("/service/:name", func(c *gin.Context) {

name := c.Param("name")
if name == "" {
throw(c, 400, "service name is required")
return
}

service := fmt.Sprintf("__yao.studio.%s", c.Param("name"))

payload, err := io.ReadAll(c.Request.Body)
if err != nil {
throw(c, 500, err.Error())
return
}

if payload == nil || len(payload) > 0 {
throw(c, 400, "file content is required")
return
}

var call cloudCall
err = jsoniter.Unmarshal(payload, &call)
if err != nil {
throw(c, 500, err.Error())
return
}

res, err := gou.Yao.Engine.Call(map[string]interface{}{}, service, call.Method, call.Args...)
if err != nil {
throw(c, 500, err.Error())
return
}

c.JSON(200, res)
c.Done()
})
}

func throw(c *gin.Context, code int, message string) {
c.JSON(code, map[string]interface{}{
"message": message,
"code": code,
})
c.Done()
}
Loading

0 comments on commit d74f74b

Please sign in to comment.