From 45b1171fb0d58b7856b554d2545e9b34dd3c1fc5 Mon Sep 17 00:00:00 2001 From: qiwang <1364512070@qq.com> Date: Tue, 25 Jun 2024 20:01:38 +0800 Subject: [PATCH 1/6] fix: update taskai 0625 Former-commit-id: 8f0176a0e31aab784995f4f4211b208b58e5c7ff --- api/internal/logic/inference/imageinferencelogic.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/api/internal/logic/inference/imageinferencelogic.go b/api/internal/logic/inference/imageinferencelogic.go index ec40d60d..b803e442 100644 --- a/api/internal/logic/inference/imageinferencelogic.go +++ b/api/internal/logic/inference/imageinferencelogic.go @@ -460,18 +460,6 @@ func getInferResult(url string, file multipart.File, fileName string, clusterNam func getInferResultModelarts(url string, file multipart.File, fileName string) (string, error) { var res Res - /* req := GetRestyRequest(20) - _, err := req. - SetFileReader("file", fileName, file). - SetHeaders(map[string]string{ - "ak": "UNEHPHO4Z7YSNPKRXFE4", - "sk": "JWXCE9qcYbc7RjpSRIWt4WgG3ZKF6Q4lPzkJReX9", - }). - SetResult(&res). - Post(url) - if err != nil { - return "", err - }*/ body, err := utils.SendRequest("POST", url, file, fileName) if err != nil { return "", err From 8428cc0ebb4f353e11f76d38ad98454a6624d8c8 Mon Sep 17 00:00:00 2001 From: jagger Date: Tue, 25 Jun 2024 20:25:47 +0800 Subject: [PATCH 2/6] fix bug Signed-off-by: jagger Former-commit-id: 04902084af3b14cf403f9cfad4eeb38e05ccee3d --- api/desc/ai/pcm-ai.api | 10 +++- api/desc/core/pcm-core.api | 9 ++++ api/desc/pcm.api | 6 +++ api/internal/handler/ai/proxyapihandler.go | 24 ++++++++++ api/internal/handler/routes.go | 5 ++ api/internal/logic/ai/proxyapilogic.go | 56 ++++++++++++++++++++++ api/internal/types/types.go | 13 +++++ 7 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 api/internal/handler/ai/proxyapihandler.go create mode 100644 api/internal/logic/ai/proxyapilogic.go diff --git a/api/desc/ai/pcm-ai.api b/api/desc/ai/pcm-ai.api index 4458d6c9..fefc7ea3 100644 --- a/api/desc/ai/pcm-ai.api +++ b/api/desc/ai/pcm-ai.api @@ -1818,4 +1818,12 @@ service AICore-api { get /getVisualizationJob (GetVisualizationJobReq) returns (GetVisualizationJobResp) @handler createVisualizationJobHandler post /CreateVisualizationJob (CreateVisualizationJobReq) returns (CreateVisualizationJobResp) -}*/ \ No newline at end of file +}*/ + +type ( + ChatReq{ + ApiUrl string `json:"apiUrl,optional"` + Method string `json:"method,optional"` + ReqData map[string]interface{} `json:"reqData"` + } +) \ No newline at end of file diff --git a/api/desc/core/pcm-core.api b/api/desc/core/pcm-core.api index 516409cc..0ad637b9 100644 --- a/api/desc/core/pcm-core.api +++ b/api/desc/core/pcm-core.api @@ -1256,5 +1256,14 @@ type ( ClusterName string `json:"clusterName" db:"cluster_name"` Status string `json:"status" db:"status"` Remark string `json:"remark" db:"remark"` + InferUrl string `json:"inferUrl"` + } +) + +type ( + CommonResp { + Code int `json:"code,omitempty"` + Msg string `json:"msg,omitempty"` + Data interface{} `json:"data,omitempty"` } ) \ No newline at end of file diff --git a/api/desc/pcm.api b/api/desc/pcm.api index 0a7b51bf..8ee57626 100644 --- a/api/desc/pcm.api +++ b/api/desc/pcm.api @@ -366,6 +366,12 @@ service pcm { @handler createVisualizationJobHandler post /ai/CreateVisualizationJob (CreateVisualizationJobReq) returns (CreateVisualizationJobResp) /******************Visualization Job Method start*************************/ + + /***********chat***********/ + @doc "文本识别" + @handler ProxyApiHandler + post /ai/chat (ChatReq) returns (CommonResp) + /******chat end***********/ } //screen接口 diff --git a/api/internal/handler/ai/proxyapihandler.go b/api/internal/handler/ai/proxyapihandler.go new file mode 100644 index 00000000..cbb732e2 --- /dev/null +++ b/api/internal/handler/ai/proxyapihandler.go @@ -0,0 +1,24 @@ +package ai + +import ( + "github.com/zeromicro/go-zero/rest/httpx" + "gitlink.org.cn/JointCloud/pcm-coordinator/api/internal/logic/ai" + "gitlink.org.cn/JointCloud/pcm-coordinator/api/internal/svc" + "gitlink.org.cn/JointCloud/pcm-coordinator/api/internal/types" + "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/repository/result" + "net/http" +) + +func ProxyApiHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.ChatReq + if err := httpx.Parse(r, &req); err != nil { + result.ParamErrorResult(r, w, err) + return + } + + l := ai.NewProxyApiLogic(r.Context(), svcCtx) + resp, err := l.ProxyApi(&req, w) + result.HttpResult(r, w, resp, err) + } +} diff --git a/api/internal/handler/routes.go b/api/internal/handler/routes.go index 2daff30f..00a8e345 100644 --- a/api/internal/handler/routes.go +++ b/api/internal/handler/routes.go @@ -437,6 +437,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/ai/CreateVisualizationJob", Handler: ai.CreateVisualizationJobHandler(serverCtx), }, + { + Method: http.MethodPost, + Path: "/ai/chat", + Handler: ai.ProxyApiHandler(serverCtx), + }, }, rest.WithPrefix("/pcm/v1"), ) diff --git a/api/internal/logic/ai/proxyapilogic.go b/api/internal/logic/ai/proxyapilogic.go new file mode 100644 index 00000000..cf201644 --- /dev/null +++ b/api/internal/logic/ai/proxyapilogic.go @@ -0,0 +1,56 @@ +package ai + +import ( + "bytes" + "context" + "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/repository/result" + tool "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/utils" + "k8s.io/apimachinery/pkg/util/json" + "net/http" + + "gitlink.org.cn/JointCloud/pcm-coordinator/api/internal/svc" + "gitlink.org.cn/JointCloud/pcm-coordinator/api/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ProxyApiLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewProxyApiLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ProxyApiLogic { + return &ProxyApiLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +type ChatResult struct { + Results string `json:"results"` +} + +func (l *ProxyApiLogic) ProxyApi(req *types.ChatReq, w http.ResponseWriter) (resp *types.CommonResp, err error) { + jsonBytes, err := json.Marshal(&req.ReqData) + // 调用第三方接口的 POST 方法 + respThirdParty, err := http.Post(req.ApiUrl, "application/json", bytes.NewBuffer(jsonBytes)) + if err != nil { + return + } + defer respThirdParty.Body.Close() + marshal, err := json.Marshal(&respThirdParty.Body) + if err != nil { + return nil, result.NewDefaultError(err.Error()) + } + json.Unmarshal(marshal, &resp) + + chatResult := &ChatResult{} + tool.Convert(resp, &chatResult.Results) + return &types.CommonResp{ + Code: respThirdParty.StatusCode, + Msg: "success", + Data: chatResult, + }, nil +} diff --git a/api/internal/types/types.go b/api/internal/types/types.go index 7ab16536..a549d98a 100644 --- a/api/internal/types/types.go +++ b/api/internal/types/types.go @@ -1179,6 +1179,13 @@ type SubTaskInfo struct { ClusterName string `json:"clusterName" db:"cluster_name"` Status string `json:"status" db:"status"` Remark string `json:"remark" db:"remark"` + InferUrl string `json:"inferUrl"` +} + +type CommonResp struct { + Code int `json:"code,omitempty"` + Msg string `json:"msg,omitempty"` + Data interface{} `json:"data,omitempty"` } type CommitHpcTaskReq struct { @@ -2869,6 +2876,12 @@ type AiTask struct { TimeElapsed int32 `json:"elapsed,optional"` } +type ChatReq struct { + ApiUrl string `json:"apiUrl,optional"` + Method string `json:"method,optional"` + ReqData map[string]interface{} `json:"reqData"` +} + type StorageScreenReq struct { } From 62923ca197a50604df1e301815e2c9860ed5dba5 Mon Sep 17 00:00:00 2001 From: qiwang <1364512070@qq.com> Date: Tue, 25 Jun 2024 20:27:54 +0800 Subject: [PATCH 3/6] fix: add iamge log 0625 Former-commit-id: c48e976f5bafd53bc153c36421374f2f382478dc --- api/internal/logic/inference/imageinferencelogic.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/internal/logic/inference/imageinferencelogic.go b/api/internal/logic/inference/imageinferencelogic.go index 151136bd..69732457 100644 --- a/api/internal/logic/inference/imageinferencelogic.go +++ b/api/internal/logic/inference/imageinferencelogic.go @@ -461,6 +461,7 @@ func getInferResult(url string, file multipart.File, fileName string, clusterNam func getInferResultModelarts(url string, file multipart.File, fileName string) (string, error) { var res Res body, err := utils.SendRequest("POST", url, file, fileName) + log.Fatalf("图形识别url: %s", url) if err != nil { return "", err } @@ -468,6 +469,7 @@ func getInferResultModelarts(url string, file multipart.File, fileName string) ( if errjson != nil { log.Fatalf("Error parsing JSON: %s", errjson) } + log.Fatalf("推理结果: %s", res.Result) return res.Result, nil } From 7cf64232706319e1e221aa5f8eceb87483a3fdbd Mon Sep 17 00:00:00 2001 From: qiwang <1364512070@qq.com> Date: Tue, 25 Jun 2024 20:41:19 +0800 Subject: [PATCH 4/6] fix: add image log 0625 Former-commit-id: 513de69ad86c3c00f985dffedd8e0e1ad8b19344 --- api/internal/logic/inference/imageinferencelogic.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/internal/logic/inference/imageinferencelogic.go b/api/internal/logic/inference/imageinferencelogic.go index 69732457..fcb20376 100644 --- a/api/internal/logic/inference/imageinferencelogic.go +++ b/api/internal/logic/inference/imageinferencelogic.go @@ -441,6 +441,7 @@ func sendInferReq(images []struct { func getInferResult(url string, file multipart.File, fileName string, clusterName string) (string, error) { if clusterName == "鹏城云脑II-modelarts" { r, err := getInferResultModelarts(url, file, fileName) + log.Printf("图形识别url: %s", url) if err != nil { return "", err } @@ -461,7 +462,7 @@ func getInferResult(url string, file multipart.File, fileName string, clusterNam func getInferResultModelarts(url string, file multipart.File, fileName string) (string, error) { var res Res body, err := utils.SendRequest("POST", url, file, fileName) - log.Fatalf("图形识别url: %s", url) + log.Printf("图形识别url: %s", url) if err != nil { return "", err } @@ -469,7 +470,7 @@ func getInferResultModelarts(url string, file multipart.File, fileName string) ( if errjson != nil { log.Fatalf("Error parsing JSON: %s", errjson) } - log.Fatalf("推理结果: %s", res.Result) + log.Printf("推理结果: %s", res.Result) return res.Result, nil } From 127c10de85e77096b071e881fbecebde247d2f6f Mon Sep 17 00:00:00 2001 From: jagger Date: Tue, 25 Jun 2024 20:53:22 +0800 Subject: [PATCH 5/6] fix bug Signed-off-by: jagger Former-commit-id: b7dc16441702ba2da13d8a55ac2c71f268045dfb --- api/internal/logic/ai/proxyapilogic.go | 53 +++++-- pkg/utils/hws/escape.go | 38 +++++ pkg/utils/hws/signer.go | 184 +++++++++++++++++++++++++ 3 files changed, 265 insertions(+), 10 deletions(-) create mode 100644 pkg/utils/hws/escape.go create mode 100644 pkg/utils/hws/signer.go diff --git a/api/internal/logic/ai/proxyapilogic.go b/api/internal/logic/ai/proxyapilogic.go index cf201644..1e7235b0 100644 --- a/api/internal/logic/ai/proxyapilogic.go +++ b/api/internal/logic/ai/proxyapilogic.go @@ -3,9 +3,11 @@ package ai import ( "bytes" "context" - "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/repository/result" + "crypto/tls" + "encoding/json" + "fmt" tool "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/utils" - "k8s.io/apimachinery/pkg/util/json" + "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/utils/hws" "net/http" "gitlink.org.cn/JointCloud/pcm-coordinator/api/internal/svc" @@ -32,24 +34,55 @@ type ChatResult struct { Results string `json:"results"` } +type ResponseData struct { + Results string `json:"results"` +} + func (l *ProxyApiLogic) ProxyApi(req *types.ChatReq, w http.ResponseWriter) (resp *types.CommonResp, err error) { + jsonBytes, err := json.Marshal(&req.ReqData) // 调用第三方接口的 POST 方法 - respThirdParty, err := http.Post(req.ApiUrl, "application/json", bytes.NewBuffer(jsonBytes)) + thirdReq, err := http.NewRequest("POST", req.ApiUrl, bytes.NewBuffer(jsonBytes)) if err != nil { return } - defer respThirdParty.Body.Close() - marshal, err := json.Marshal(&respThirdParty.Body) - if err != nil { - return nil, result.NewDefaultError(err.Error()) + + signer := &hws.Signer{ + Key: "UNEHPHO4Z7YSNPKRXFE4", + Secret: "JWXCE9qcYbc7RjpSRIWt4WgG3ZKF6Q4lPzkJReX9", + } + + if err := signer.Sign(thirdReq); err != nil { + return nil, err + } + + // 设置client信任所有证书 + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client := &http.Client{ + Transport: tr, + } + + thirdReq.Header.Set("X-Project-Id", "d18190e28e3f45a281ef0b0696ec9d52") + thirdReq.Header.Set("x-stage", "RELEASE") + thirdReq.Header.Set("Authorization", thirdReq.Header.Get(hws.HeaderXAuthorization)) + thirdReq.Header.Set("X-Sdk-Date", thirdReq.Header.Get(hws.HeaderXDateTime)) + thirdReq.Header.Set("Content-Type", "application/json") + + thirdResp, err := client.Do(thirdReq) + + defer thirdReq.Body.Close() + var responseData ResponseData + decoder := json.NewDecoder(thirdResp.Body) + if err := decoder.Decode(&responseData); err != nil { + fmt.Println("Error decoding response:", err) } - json.Unmarshal(marshal, &resp) chatResult := &ChatResult{} - tool.Convert(resp, &chatResult.Results) + tool.Convert(responseData, &chatResult) return &types.CommonResp{ - Code: respThirdParty.StatusCode, + Code: thirdResp.StatusCode, Msg: "success", Data: chatResult, }, nil diff --git a/pkg/utils/hws/escape.go b/pkg/utils/hws/escape.go new file mode 100644 index 00000000..5c311ce4 --- /dev/null +++ b/pkg/utils/hws/escape.go @@ -0,0 +1,38 @@ +package hws + +func shouldEscape(c byte) bool { + if 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_' || c == '-' || c == '~' || c == '.' { + return false + } + return true +} + +func Escape(s string) string { + hexCount := 0 + for i := 0; i < len(s); i++ { + c := s[i] + if shouldEscape(c) { + hexCount++ + } + } + + if hexCount == 0 { + return s + } + + t := make([]byte, len(s)+2*hexCount) + j := 0 + for i := 0; i < len(s); i++ { + switch c := s[i]; { + case shouldEscape(c): + t[j] = '%' + t[j+1] = "0123456789ABCDEF"[c>>4] + t[j+2] = "0123456789ABCDEF"[c&15] + j += 3 + default: + t[j] = s[i] + j++ + } + } + return string(t) +} diff --git a/pkg/utils/hws/signer.go b/pkg/utils/hws/signer.go new file mode 100644 index 00000000..1455c82a --- /dev/null +++ b/pkg/utils/hws/signer.go @@ -0,0 +1,184 @@ +package hws + +import ( + "bytes" + "crypto/hmac" + "crypto/sha256" + "fmt" + "io/ioutil" + "net/http" + "sort" + "strings" + "time" +) + +const ( + DateFormat = "20060102T150405Z" + SignAlgorithm = "SDK-HMAC-SHA256" + HeaderXDateTime = "X-Sdk-Date" + HeaderXHost = "host" + HeaderXAuthorization = "Authorization" + HeaderXContentSha256 = "X-Sdk-Content-Sha256" +) + +func hmacsha256(keyByte []byte, dataStr string) ([]byte, error) { + hm := hmac.New(sha256.New, []byte(keyByte)) + if _, err := hm.Write([]byte(dataStr)); err != nil { + return nil, err + } + return hm.Sum(nil), nil +} + +func CanonicalRequest(request *http.Request, signedHeaders []string) (string, error) { + var hexencode string + var err error + if hex := request.Header.Get(HeaderXContentSha256); hex != "" { + hexencode = hex + } else { + bodyData, err := RequestPayload(request) + if err != nil { + return "", err + } + hexencode, err = HexEncodeSHA256Hash(bodyData) + if err != nil { + return "", err + } + } + return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s", request.Method, CanonicalURI(request), CanonicalQueryString(request), CanonicalHeaders(request, signedHeaders), strings.Join(signedHeaders, ";"), hexencode), err +} + +func CanonicalURI(request *http.Request) string { + pattens := strings.Split(request.URL.Path, "/") + var uriSlice []string + for _, v := range pattens { + uriSlice = append(uriSlice, Escape(v)) + } + urlpath := strings.Join(uriSlice, "/") + if len(urlpath) == 0 || urlpath[len(urlpath)-1] != '/' { + urlpath = urlpath + "/" + } + return urlpath +} + +func CanonicalQueryString(request *http.Request) string { + var keys []string + queryMap := request.URL.Query() + for key := range queryMap { + keys = append(keys, key) + } + sort.Strings(keys) + var query []string + for _, key := range keys { + k := Escape(key) + sort.Strings(queryMap[key]) + for _, v := range queryMap[key] { + kv := fmt.Sprintf("%s=%s", k, Escape(v)) + query = append(query, kv) + } + } + queryStr := strings.Join(query, "&") + request.URL.RawQuery = queryStr + return queryStr +} + +func CanonicalHeaders(request *http.Request, signerHeaders []string) string { + var canonicalHeaders []string + header := make(map[string][]string) + for k, v := range request.Header { + header[strings.ToLower(k)] = v + } + for _, key := range signerHeaders { + value := header[key] + if strings.EqualFold(key, HeaderXHost) { + value = []string{request.Host} + } + sort.Strings(value) + for _, v := range value { + canonicalHeaders = append(canonicalHeaders, key+":"+strings.TrimSpace(v)) + } + } + return fmt.Sprintf("%s\n", strings.Join(canonicalHeaders, "\n")) +} + +func SignedHeaders(r *http.Request) []string { + var signedHeaders []string + for key := range r.Header { + signedHeaders = append(signedHeaders, strings.ToLower(key)) + } + sort.Strings(signedHeaders) + return signedHeaders +} + +func RequestPayload(request *http.Request) ([]byte, error) { + if request.Body == nil { + return []byte(""), nil + } + bodyByte, err := ioutil.ReadAll(request.Body) + if err != nil { + return []byte(""), err + } + request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyByte)) + return bodyByte, err +} + +func StringToSign(canonicalRequest string, t time.Time) (string, error) { + hashStruct := sha256.New() + _, err := hashStruct.Write([]byte(canonicalRequest)) + if err != nil { + return "", err + } + return fmt.Sprintf("%s\n%s\n%x", + SignAlgorithm, t.UTC().Format(DateFormat), hashStruct.Sum(nil)), nil +} + +func SignStringToSign(stringToSign string, signingKey []byte) (string, error) { + hmsha, err := hmacsha256(signingKey, stringToSign) + return fmt.Sprintf("%x", hmsha), err +} + +func HexEncodeSHA256Hash(body []byte) (string, error) { + hashStruct := sha256.New() + if len(body) == 0 { + body = []byte("") + } + _, err := hashStruct.Write(body) + return fmt.Sprintf("%x", hashStruct.Sum(nil)), err +} + +func AuthHeaderValue(signatureStr, accessKeyStr string, signedHeaders []string) string { + return fmt.Sprintf("%s Access=%s, SignedHeaders=%s, Signature=%s", SignAlgorithm, accessKeyStr, strings.Join(signedHeaders, ";"), signatureStr) +} + +type Signer struct { + Key string + Secret string +} + +func (s *Signer) Sign(request *http.Request) error { + var t time.Time + var err error + var date string + if date = request.Header.Get(HeaderXDateTime); date != "" { + t, err = time.Parse(DateFormat, date) + } + if err != nil || date == "" { + t = time.Now() + request.Header.Set(HeaderXDateTime, t.UTC().Format(DateFormat)) + } + signedHeaders := SignedHeaders(request) + canonicalRequest, err := CanonicalRequest(request, signedHeaders) + if err != nil { + return err + } + stringToSignStr, err := StringToSign(canonicalRequest, t) + if err != nil { + return err + } + signatureStr, err := SignStringToSign(stringToSignStr, []byte(s.Secret)) + if err != nil { + return err + } + authValueStr := AuthHeaderValue(signatureStr, s.Key, signedHeaders) + request.Header.Set(HeaderXAuthorization, authValueStr) + return nil +} From 02d5da24f031a319c9b99c4cba0423b072c7c603 Mon Sep 17 00:00:00 2001 From: qiwang <1364512070@qq.com> Date: Wed, 26 Jun 2024 16:58:52 +0800 Subject: [PATCH 6/6] fix: update vminfo 0626 Former-commit-id: d3d9e2069595db59945f20b3cd422fb17bdbd71f --- api/client/types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client/types.go b/api/client/types.go index bf5c676d..2aa28e22 100644 --- a/api/client/types.go +++ b/api/client/types.go @@ -175,7 +175,7 @@ type VmInfo struct { //DeletedAt string `json:"deletedAt,omitempty"` VmName string `json:"vmName,omitempty"` Replicas int64 `json:"replicas,omitempty"` - ServerId string `json:"serverId,omitempty"` + //ServerId string `json:"serverId,omitempty"` } type ResourceStats struct {