From 81b20a0654590c798348c466af99f8aac5a10584 Mon Sep 17 00:00:00 2001 From: Bruce Date: Thu, 12 May 2022 18:29:54 +0800 Subject: [PATCH] feat: batchExec --- config/webpack.prod.js | 2 +- .../handler/gateway/batchexecngqlhandler.go | 33 +++++++++++++++ .../api/studio/internal/handler/routes.go | 5 +++ .../logic/gateway/batchexecngqllogic.go | 29 +++++++++++++ .../api/studio/internal/service/gateway.go | 41 +++++++++++++++++++ server-v2/api/studio/internal/types/types.go | 6 +++ server-v2/api/studio/pkg/auth/authorize.go | 17 +++++--- server-v2/api/studio/pkg/base/types.go | 2 - server-v2/api/studio/restapi/gateway.api | 10 ++++- 9 files changed, 135 insertions(+), 10 deletions(-) create mode 100644 server-v2/api/studio/internal/handler/gateway/batchexecngqlhandler.go create mode 100644 server-v2/api/studio/internal/logic/gateway/batchexecngqllogic.go diff --git a/config/webpack.prod.js b/config/webpack.prod.js index e0f19da4..2fe7b62f 100644 --- a/config/webpack.prod.js +++ b/config/webpack.prod.js @@ -13,7 +13,7 @@ const publicConfig = { path: path.join(__dirname, '../dist/'), filename: '[name].[chunkhash].js', chunkFilename: '[name].[contenthash].js', - publicPath: '/assets/', + publicPath: '/', }, module: { rules: [ diff --git a/server-v2/api/studio/internal/handler/gateway/batchexecngqlhandler.go b/server-v2/api/studio/internal/handler/gateway/batchexecngqlhandler.go new file mode 100644 index 00000000..56338b7f --- /dev/null +++ b/server-v2/api/studio/internal/handler/gateway/batchexecngqlhandler.go @@ -0,0 +1,33 @@ +// Code generated by goctl. DO NOT EDIT. +package gateway + +import ( + "net/http" + + "github.com/vesoft-inc/go-pkg/validator" + "github.com/vesoft-inc/nebula-studio/server/api/studio/pkg/ecode" + + "github.com/vesoft-inc/nebula-studio/server/api/studio/internal/logic/gateway" + "github.com/vesoft-inc/nebula-studio/server/api/studio/internal/svc" + "github.com/vesoft-inc/nebula-studio/server/api/studio/internal/types" + "github.com/zeromicro/go-zero/rest/httpx" +) + +func BatchExecNGQLHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.BatchExecNGQLParams + if err := httpx.Parse(r, &req); err != nil { + err = ecode.WithCode(ecode.ErrParam, err) + svcCtx.ResponseHandler.Handle(w, r, nil, err) + return + } + if err := validator.Struct(req); err != nil { + svcCtx.ResponseHandler.Handle(w, r, nil, err) + return + } + + l := gateway.NewBatchExecNGQLLogic(r.Context(), svcCtx) + data, err := l.BatchExecNGQL(req) + svcCtx.ResponseHandler.Handle(w, r, data, err) + } +} diff --git a/server-v2/api/studio/internal/handler/routes.go b/server-v2/api/studio/internal/handler/routes.go index 3ac7849a..c6b5e76d 100644 --- a/server-v2/api/studio/internal/handler/routes.go +++ b/server-v2/api/studio/internal/handler/routes.go @@ -30,6 +30,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/exec", Handler: gateway.ExecNGQLHandler(serverCtx), }, + { + Method: http.MethodPost, + Path: "/batchExec", + Handler: gateway.BatchExecNGQLHandler(serverCtx), + }, }, rest.WithPrefix("/api-nebula/db"), ) diff --git a/server-v2/api/studio/internal/logic/gateway/batchexecngqllogic.go b/server-v2/api/studio/internal/logic/gateway/batchexecngqllogic.go new file mode 100644 index 00000000..9d9d52f0 --- /dev/null +++ b/server-v2/api/studio/internal/logic/gateway/batchexecngqllogic.go @@ -0,0 +1,29 @@ +package gateway + +import ( + "context" + + "github.com/vesoft-inc/nebula-studio/server/api/studio/internal/service" + "github.com/vesoft-inc/nebula-studio/server/api/studio/internal/svc" + "github.com/vesoft-inc/nebula-studio/server/api/studio/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type BatchExecNGQLLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewBatchExecNGQLLogic(ctx context.Context, svcCtx *svc.ServiceContext) BatchExecNGQLLogic { + return BatchExecNGQLLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *BatchExecNGQLLogic) BatchExecNGQL(req types.BatchExecNGQLParams) (*types.AnyResponse, error) { + return service.NewGatewayService(l.ctx, l.svcCtx).BatchExecNGQL(&req) +} diff --git a/server-v2/api/studio/internal/service/gateway.go b/server-v2/api/studio/internal/service/gateway.go index cf60be23..797a28e7 100644 --- a/server-v2/api/studio/internal/service/gateway.go +++ b/server-v2/api/studio/internal/service/gateway.go @@ -2,10 +2,12 @@ package service import ( "context" + "strings" "github.com/vesoft-inc/nebula-http-gateway/ccore/nebula/gateway/dao" "github.com/vesoft-inc/nebula-studio/server/api/studio/internal/svc" "github.com/vesoft-inc/nebula-studio/server/api/studio/internal/types" + "github.com/vesoft-inc/nebula-studio/server/api/studio/pkg/base" "github.com/vesoft-inc/nebula-studio/server/api/studio/pkg/ecode" "github.com/zeromicro/go-zero/core/logx" @@ -16,6 +18,7 @@ var _ GatewayService = (*gatewayService)(nil) type ( GatewayService interface { ExecNGQL(request *types.ExecNGQLParams) (*types.AnyResponse, error) + BatchExecNGQL(request *types.BatchExecNGQLParams) (*types.AnyResponse, error) ConnectDB(request *types.ConnectDBParams) (*types.ConnectDBResult, error) DisconnectDB(request *types.DisconnectDBParams) (*types.AnyResponse, error) } @@ -55,3 +58,41 @@ func (s *gatewayService) ExecNGQL(request *types.ExecNGQLParams) (*types.AnyResp } return &types.AnyResponse{Data: execute}, nil } + +func (s *gatewayService) BatchExecNGQL(request *types.BatchExecNGQLParams) (*types.AnyResponse, error) { + data := make([]map[string]interface{}, 0) + + NSID := request.NSID + gqls := request.Gqls + paramList := request.ParamList + + for _, gql := range gqls { + execute, _, err := dao.Execute(NSID, gql, make([]string, 0)) + gqlRes := make(map[string]interface{}) + gqlRes["gql"] = gql + if err != nil { + gqlRes["message"] = err.Error() + gqlRes["code"] = base.Error + } else { + gqlRes["code"] = base.Success + } + gqlRes["data"] = execute + data = append(data, gqlRes) + } + + if len(paramList) > 0 { + execute, _, err := dao.Execute(NSID, "", paramList) + gqlRes := make(map[string]interface{}) + gqlRes["gql"] = strings.Join(paramList, "; ") + if err != nil { + gqlRes["message"] = err.Error() + gqlRes["code"] = base.Error + } else { + gqlRes["code"] = base.Success + } + gqlRes["data"] = execute + data = append(data, gqlRes) + } + + return &types.AnyResponse{Data: data}, nil +} diff --git a/server-v2/api/studio/internal/types/types.go b/server-v2/api/studio/internal/types/types.go index 1e2072ea..ee697dba 100644 --- a/server-v2/api/studio/internal/types/types.go +++ b/server-v2/api/studio/internal/types/types.go @@ -11,6 +11,12 @@ type ExecNGQLParams struct { NSID string `form:"NSID"` } +type BatchExecNGQLParams struct { + Gqls []string `json:"gqls"` + ParamList []string `json:"paramList,optional"` + NSID string `form:"NSID"` +} + type ConnectDBParams struct { Address string `json:"address"` Port int `json:"port"` diff --git a/server-v2/api/studio/pkg/auth/authorize.go b/server-v2/api/studio/pkg/auth/authorize.go index 745df935..6cc6bced 100644 --- a/server-v2/api/studio/pkg/auth/authorize.go +++ b/server-v2/api/studio/pkg/auth/authorize.go @@ -35,6 +35,11 @@ type ( } ) +var ( + tokenName = "explorer_token" + nsidName = "explorer_nsid" +) + func CreateToken(authData *AuthData, config *config.Config) (string, error) { now := time.Now() expiresAt := now.Add(time.Duration(config.Auth.AccessExpire) * time.Second).Unix() @@ -136,14 +141,14 @@ func AuthMiddlewareWithCtx(svcCtx *svc.ServiceContext) rest.Middleware { } token := http.Cookie{ - Name: "token", + Name: tokenName, Value: tokenString, Path: "/", HttpOnly: true, MaxAge: int(configAuth.AccessExpire), } NSID := http.Cookie{ - Name: "NSID", + Name: nsidName, Value: clientInfo.ClientID, Path: "/", HttpOnly: true, @@ -159,20 +164,20 @@ func AuthMiddlewareWithCtx(svcCtx *svc.ServiceContext) rest.Middleware { return } - NSIDCookie, NSIDErr := r.Cookie("NSID") + NSIDCookie, NSIDErr := r.Cookie(nsidName) if NSIDErr == nil { // Add NSID to request query utils.AddQueryParams(r, map[string]string{"NSID": NSIDCookie.Value}) } if strings.HasSuffix(r.URL.Path, "/disconnect") { - w.Header().Set("Set-Cookie", utils.DisabledCookie("token").String()) - w.Header().Add("Set-Cookie", utils.DisabledCookie("NSID").String()) + w.Header().Set("Set-Cookie", utils.DisabledCookie(tokenName).String()) + w.Header().Add("Set-Cookie", utils.DisabledCookie(nsidName).String()) next(w, r) return } - tokenCookie, tokenErr := r.Cookie("token") + tokenCookie, tokenErr := r.Cookie(tokenName) if NSIDErr != nil || tokenErr != nil { if NSIDErr != nil { svcCtx.ResponseHandler.Handle(w, r, nil, ecode.WithSessionMessage(NSIDErr)) diff --git a/server-v2/api/studio/pkg/base/types.go b/server-v2/api/studio/pkg/base/types.go index ef6f1c6f..de47fbb6 100644 --- a/server-v2/api/studio/pkg/base/types.go +++ b/server-v2/api/studio/pkg/base/types.go @@ -7,6 +7,4 @@ type Result interface{} const ( Error StatusCode = -1 Success StatusCode = 0 - // TODO: need to del it - AuthorizationError StatusCode = 401 ) diff --git a/server-v2/api/studio/restapi/gateway.api b/server-v2/api/studio/restapi/gateway.api index c4c7a1b5..baee6de6 100644 --- a/server-v2/api/studio/restapi/gateway.api +++ b/server-v2/api/studio/restapi/gateway.api @@ -6,6 +6,11 @@ type ( ParamList []string `json:"paramList,optional"` NSID string `form:"NSID"` } + BatchExecNGQLParams { + Gqls []string `json:"gqls"` + ParamList []string `json:"paramList,optional"` + NSID string `form:"NSID"` + } ConnectDBParams { Address string `json:"address"` Port int `json:"port"` @@ -18,7 +23,6 @@ type ( DisconnectDBParams { NSID string `form:"NSID,optional"` } - AnyResponse { Data interface{} `json:"data"` } @@ -33,6 +37,10 @@ service studio-api { @doc "Exec NGQL" @handler ExecNGQL post /exec(ExecNGQLParams) returns (AnyResponse) + + @doc "BatchExec NGQL" + @handler BatchExecNGQL + post /batchExec(BatchExecNGQLParams) returns (AnyResponse) } @server(