JCS-pub/hub/sdk/api/hub_io.go

243 lines
4.7 KiB
Go

package api
import (
"fmt"
"io"
"net/url"
"gitlink.org.cn/cloudream/common/consts/errorcode"
"gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec"
"gitlink.org.cn/cloudream/common/utils/http2"
"gitlink.org.cn/cloudream/common/utils/io2"
"gitlink.org.cn/cloudream/common/utils/serder"
)
const GetStreamPath = "/hubIO/getStream"
type GetStreamReq struct {
PlanID exec.PlanID `json:"planID"`
VarID exec.VarID `json:"varID"`
SignalID exec.VarID `json:"signalID"`
Signal exec.VarValue `json:"signal"`
}
func (c *Client) GetStream(req GetStreamReq) (io.ReadCloser, error) {
targetUrl, err := url.JoinPath(c.cfg.URL, GetStreamPath)
if err != nil {
return nil, err
}
body, err := serder.ObjectToJSONEx(req)
if err != nil {
return nil, fmt.Errorf("request to json: %w", err)
}
resp, err := http2.GetJSON(targetUrl, http2.RequestParam{
Body: body,
})
if err != nil {
return nil, err
}
cr := http2.NewChunkedReader(resp.Body)
_, str, err := cr.NextPart()
if err != nil {
return nil, fmt.Errorf("reading response: %w", err)
}
return io2.DelegateReadCloser(str, func() error {
cr.Close()
return nil
}), nil
}
const SendStreamPath = "/hubIO/sendStream"
type SendStreamReq struct {
SendStreamInfo
Stream io.ReadCloser
}
type SendStreamInfo struct {
PlanID exec.PlanID `json:"planID"`
VarID exec.VarID `json:"varID"`
}
func (c *Client) SendStream(req SendStreamReq) error {
targetUrl, err := url.JoinPath(c.cfg.URL, SendStreamPath)
if err != nil {
return err
}
pr, pw := io.Pipe()
errCh := make(chan error, 1)
go func() {
cw := http2.NewChunkedWriter(pw)
infoJSON, err := serder.ObjectToJSONEx(req)
if err != nil {
cw.Abort(fmt.Sprintf("info to json: %v", err))
errCh <- fmt.Errorf("info to json: %w", err)
return
}
if err := cw.WriteDataPart("info", infoJSON); err != nil {
cw.Close()
errCh <- fmt.Errorf("write info: %w", err)
return
}
_, err = cw.WriteStreamPart("stream", req.Stream)
if err != nil {
cw.Close()
errCh <- fmt.Errorf("write stream: %w", err)
return
}
err = cw.Finish()
if err != nil {
errCh <- fmt.Errorf("finish chunked writer: %w", err)
return
}
}()
resp, err := http2.PostChunked2(targetUrl, http2.Chunked2RequestParam{
Body: pr,
})
if err != nil {
return err
}
err = <-errCh
if err != nil {
return err
}
codeResp, err := ParseJSONResponse[response[any]](resp)
if err != nil {
return err
}
if codeResp.Code == errorcode.OK {
return nil
}
return codeResp.ToError()
}
const ExecuteIOPlanPath = "/hubIO/executeIOPlan"
type ExecuteIOPlanReq struct {
Plan exec.Plan `json:"plan"`
}
func (c *Client) ExecuteIOPlan(req ExecuteIOPlanReq) error {
targetUrl, err := url.JoinPath(c.cfg.URL, ExecuteIOPlanPath)
if err != nil {
return err
}
body, err := serder.ObjectToJSONEx(req)
if err != nil {
return fmt.Errorf("request to json: %w", err)
}
resp, err := http2.PostJSON(targetUrl, http2.RequestParam{
Body: body,
})
if err != nil {
return err
}
codeResp, err := ParseJSONResponse[response[any]](resp)
if err != nil {
return err
}
if codeResp.Code == errorcode.OK {
return nil
}
return codeResp.ToError()
}
const SendVarPath = "/hubIO/sendVar"
type SendVarReq struct {
PlanID exec.PlanID `json:"planID"`
VarID exec.VarID `json:"varID"`
VarValue exec.VarValue `json:"varValue"`
}
func (c *Client) SendVar(req SendVarReq) error {
targetUrl, err := url.JoinPath(c.cfg.URL, SendVarPath)
if err != nil {
return err
}
body, err := serder.ObjectToJSONEx(req)
if err != nil {
return fmt.Errorf("request to json: %w", err)
}
resp, err := http2.PostJSON(targetUrl, http2.RequestParam{
Body: body,
})
if err != nil {
return err
}
jsonResp, err := ParseJSONResponse[response[any]](resp)
if err != nil {
return err
}
if jsonResp.Code == errorcode.OK {
return nil
}
return jsonResp.ToError()
}
const GetVarPath = "/hubIO/getVar"
type GetVarReq struct {
PlanID exec.PlanID `json:"planID"`
VarID exec.VarID `json:"varID"`
SignalID exec.VarID `json:"signalID"`
Signal exec.VarValue `json:"signal"`
}
type GetVarResp struct {
Value exec.VarValue `json:"value"`
}
func (c *Client) GetVar(req GetVarReq) (*GetVarResp, error) {
targetUrl, err := url.JoinPath(c.cfg.URL, GetVarPath)
if err != nil {
return nil, err
}
body, err := serder.ObjectToJSONEx(req)
if err != nil {
return nil, fmt.Errorf("request to json: %w", err)
}
resp, err := http2.GetJSON(targetUrl, http2.RequestParam{
Body: body,
})
if err != nil {
return nil, err
}
jsonResp, err := ParseJSONResponse[response[GetVarResp]](resp)
if err != nil {
return nil, err
}
if jsonResp.Code == errorcode.OK {
return &jsonResp.Data, nil
}
return nil, jsonResp.ToError()
}