mirror of
https://github.com/go-micro/go-micro.git
synced 2025-11-23 21:44:41 +02:00
107 lines
3.0 KiB
Go
107 lines
3.0 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"github.com/asim/go-micro/cmd/dashboard/v4/handler/route"
|
|
cgrpc "github.com/asim/go-micro/plugins/client/grpc/v4"
|
|
chttp "github.com/asim/go-micro/plugins/client/http/v4"
|
|
cmucp "github.com/asim/go-micro/plugins/client/mucp/v4"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/gin-gonic/gin/render"
|
|
"go-micro.dev/v4/client"
|
|
"go-micro.dev/v4/errors"
|
|
"go-micro.dev/v4/registry"
|
|
"go-micro.dev/v4/selector"
|
|
)
|
|
|
|
type service struct {
|
|
client client.Client
|
|
registry registry.Registry
|
|
}
|
|
|
|
func NewRouteRegistrar(client client.Client, registry registry.Registry) route.Registrar {
|
|
return service{client: client, registry: registry}
|
|
}
|
|
|
|
func (s service) RegisterAuthRoute(router gin.IRoutes) {
|
|
router.POST("/api/client/endpoint/call", s.CallEndpoint)
|
|
}
|
|
|
|
func (s service) RegisterNonAuthRoute(router gin.IRoutes) {
|
|
}
|
|
|
|
// @Security ApiKeyAuth
|
|
// @Tags Client
|
|
// @ID client_callEndpoint
|
|
// @Param input body callRequest true "request"
|
|
// @Success 200 {object} object "success"
|
|
// @Failure 400 {object} string
|
|
// @Failure 401 {object} string
|
|
// @Failure 500 {object} string
|
|
// @Router /api/client/endpoint/call [post]
|
|
func (s *service) CallEndpoint(ctx *gin.Context) {
|
|
var req callRequest
|
|
if err := ctx.ShouldBindJSON(&req); nil != err {
|
|
ctx.Render(400, render.String{Format: err.Error()})
|
|
return
|
|
}
|
|
var callReq json.RawMessage
|
|
if len(req.Request) > 0 {
|
|
if err := json.Unmarshal([]byte(req.Request), &callReq); err != nil {
|
|
ctx.Render(400, render.String{Format: "parse request failed: %s", Data: []interface{}{err.Error()}})
|
|
return
|
|
}
|
|
}
|
|
services, err := s.registry.GetService(req.Service)
|
|
if err != nil {
|
|
ctx.Render(400, render.String{Format: err.Error()})
|
|
return
|
|
}
|
|
var c client.Client
|
|
for _, srv := range services {
|
|
if len(req.Version) > 0 && req.Version != srv.Version {
|
|
continue
|
|
}
|
|
if len(srv.Nodes) == 0 {
|
|
ctx.Render(400, render.String{Format: "service node not found"})
|
|
return
|
|
}
|
|
switch srv.Nodes[0].Metadata["server"] {
|
|
case "grpc":
|
|
c = cgrpc.NewClient()
|
|
case "http":
|
|
c = chttp.NewClient()
|
|
case "mucp":
|
|
c = cmucp.NewClient()
|
|
default:
|
|
c = s.client
|
|
}
|
|
break
|
|
}
|
|
if c == nil {
|
|
ctx.Render(400, render.String{Format: "service not found"})
|
|
return
|
|
}
|
|
var resp json.RawMessage
|
|
callOpts := []client.CallOption{}
|
|
if len(req.Version) > 0 {
|
|
callOpts = append(callOpts, client.WithSelectOption(selector.WithFilter(selector.FilterVersion(req.Version))))
|
|
}
|
|
requestOpts := []client.RequestOption{client.WithContentType("application/json")}
|
|
if req.Timeout > 0 {
|
|
callOpts = append(callOpts, client.WithRequestTimeout(time.Duration(req.Timeout)*time.Second))
|
|
}
|
|
if err := c.Call(context.TODO(), client.NewRequest(req.Service, req.Endpoint, callReq, requestOpts...), &resp, callOpts...); err != nil {
|
|
if merr := errors.Parse(err.Error()); merr != nil {
|
|
ctx.JSON(200, gin.H{"success": false, "error": merr})
|
|
} else {
|
|
ctx.JSON(200, gin.H{"success": false, "error": err.Error})
|
|
}
|
|
return
|
|
}
|
|
ctx.JSON(200, resp)
|
|
}
|