|
|
@@ -0,0 +1,114 @@
|
|
|
+package gateway
|
|
|
+
|
|
|
+import (
|
|
|
+ "git.sxidc.com/go-framework/baize/framework/binding"
|
|
|
+ "git.sxidc.com/go-framework/baize/framework/binding/request"
|
|
|
+ "git.sxidc.com/go-framework/baize/framework/binding/response"
|
|
|
+ "git.sxidc.com/go-framework/baize/framework/core/api"
|
|
|
+ "git.sxidc.com/go-framework/baize/framework/core/domain"
|
|
|
+ "git.sxidc.com/go-framework/baize/framework/core/infrastructure"
|
|
|
+ "git.sxidc.com/go-framework/baize/framework/core/infrastructure/logger"
|
|
|
+ "git.sxidc.com/go-tools/utils/http_client"
|
|
|
+ "git.sxidc.com/service-supports/fserr"
|
|
|
+ "io"
|
|
|
+ "net/http"
|
|
|
+ "strings"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+func (gw *Gateway) BodyMapping(binder *binding.Binder, bodyMapping *BodyMapping, middlewares ...api.Handler) {
|
|
|
+ bodyMapping.bind(binder, gw.httpClient, gw.options.timeoutSec, middlewares...)
|
|
|
+}
|
|
|
+
|
|
|
+type BodyMapping struct {
|
|
|
+ HttpMethod string
|
|
|
+ RelativePath string
|
|
|
+ ToUrl string
|
|
|
+
|
|
|
+ BodyMappingFunc func(body []byte) ([]byte, error)
|
|
|
+}
|
|
|
+
|
|
|
+func (bodyMapping *BodyMapping) bind(binder *binding.Binder, httpClient *http_client.Client, timeoutSec int64, middlewares ...api.Handler) {
|
|
|
+ binding.Bind[any](binder, &binding.BindItem[any]{
|
|
|
+ Method: bodyMapping.HttpMethod,
|
|
|
+ SimpleBindItem: &binding.SimpleBindItem[any]{
|
|
|
+ Path: bodyMapping.RelativePath,
|
|
|
+ ResponseFunc: response.NoResponse,
|
|
|
+ ServiceFunc: func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (any, error) {
|
|
|
+ body, err := io.ReadAll(c.Request.Body)
|
|
|
+ if err != nil {
|
|
|
+ logger.GetInstance().Error(err)
|
|
|
+ c.AbortWithStatus(http.StatusBadGateway)
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ defer func() {
|
|
|
+ err := c.Request.Body.Close()
|
|
|
+ if err != nil {
|
|
|
+ logger.GetInstance().Error(err)
|
|
|
+ c.AbortWithStatus(http.StatusBadGateway)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ if bodyMapping.BodyMappingFunc != nil {
|
|
|
+ newBody, err := bodyMapping.BodyMappingFunc(body)
|
|
|
+ if err != nil {
|
|
|
+ logger.GetInstance().Error(err)
|
|
|
+ c.AbortWithStatus(http.StatusBadGateway)
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ body = newBody
|
|
|
+ }
|
|
|
+
|
|
|
+ headers := make(map[string]string)
|
|
|
+ for key, values := range c.Request.Header {
|
|
|
+ headers[key] = strings.Join(values, ",")
|
|
|
+ }
|
|
|
+
|
|
|
+ var httpResponse *http_client.Response
|
|
|
+ httpRequest := httpClient.
|
|
|
+ NewRequest(http_client.WithNewRequestTimeout(time.Duration(timeoutSec) * time.Second))
|
|
|
+
|
|
|
+ switch bodyMapping.HttpMethod {
|
|
|
+ case http.MethodPost:
|
|
|
+ resp, err := httpRequest.Post(bodyMapping.ToUrl, body, http_client.WithRequestHeaders(headers))
|
|
|
+ if err != nil {
|
|
|
+ logger.GetInstance().Error(err)
|
|
|
+ c.AbortWithStatus(http.StatusBadGateway)
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ httpResponse = resp
|
|
|
+ case http.MethodPut:
|
|
|
+ resp, err := httpRequest.Put(bodyMapping.ToUrl, body, http_client.WithRequestHeaders(headers))
|
|
|
+ if err != nil {
|
|
|
+ logger.GetInstance().Error(err)
|
|
|
+ c.AbortWithStatus(http.StatusBadGateway)
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ httpResponse = resp
|
|
|
+ default:
|
|
|
+ err := fserr.New("不支持Body传递参数")
|
|
|
+ logger.GetInstance().Error(err)
|
|
|
+ c.AbortWithStatus(http.StatusBadGateway)
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ c.Status(http.StatusOK)
|
|
|
+
|
|
|
+ _, err = c.Writer.Write(httpResponse.Body())
|
|
|
+ if err != nil {
|
|
|
+ logger.GetInstance().Error(err)
|
|
|
+ c.AbortWithStatus(http.StatusBadGateway)
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ c.Writer.Flush()
|
|
|
+
|
|
|
+ return nil, nil
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }, middlewares...)
|
|
|
+}
|