174 lines
6.2 KiB
Go
174 lines
6.2 KiB
Go
package orbit
|
||
|
||
import (
|
||
"context"
|
||
"errors"
|
||
)
|
||
|
||
func workflowActivationPath(id, key string, activation ...string) (string, error) {
|
||
if !validID(id) || !workflowVersionName(key) {
|
||
return "", errors.New("invalid workflow step identity")
|
||
}
|
||
path := "/v1/workflows/" + id + "/steps/" + key + "/activations"
|
||
for _, v := range activation {
|
||
if !validID(v) {
|
||
return "", errors.New("invalid activation id")
|
||
}
|
||
path += "/" + v
|
||
}
|
||
return path, nil
|
||
}
|
||
func workflowSignalPath(id string, signal ...string) (string, error) {
|
||
if !validID(id) {
|
||
return "", errors.New("invalid workflow id")
|
||
}
|
||
path := "/v1/workflows/" + id + "/signals"
|
||
for _, v := range signal {
|
||
if !validID(v) {
|
||
return "", errors.New("invalid signal id")
|
||
}
|
||
path += "/" + v
|
||
}
|
||
return path, nil
|
||
}
|
||
func historyResponseSize(n int, in HistoryPageRequest) bool {
|
||
limit := in.Limit
|
||
if limit == 0 {
|
||
limit = 20
|
||
}
|
||
return n <= limit
|
||
}
|
||
|
||
// ListWorkflowActivations 返回指定逻辑步骤的各次激活摘要,代次倒序;跨页状态可继续变化。
|
||
func (c *Client) ListWorkflowActivations(ctx context.Context, id, key string, in HistoryPageRequest) (WorkflowActivationPage, error) {
|
||
var out WorkflowActivationPage
|
||
path, err := workflowActivationPath(id, key)
|
||
if err != nil {
|
||
return out, err
|
||
}
|
||
query, err := historyPageQuery(in)
|
||
if err != nil {
|
||
return out, err
|
||
}
|
||
if err = c.call(ctx, "GET", path+query, "", nil, &out); err != nil {
|
||
return WorkflowActivationPage{}, err
|
||
}
|
||
if out.InstanceID != id || !validID(out.StepID) || out.Revision == 0 || out.Items == nil || !historyResponseSize(len(out.Items), in) {
|
||
return WorkflowActivationPage{}, errors.New("invalid activation page")
|
||
}
|
||
for i, a := range out.Items {
|
||
if !validID(a.ID) || a.StepID != out.StepID || a.Sequence == 0 || a.Revision == 0 || i > 0 && a.Sequence >= out.Items[i-1].Sequence {
|
||
return WorkflowActivationPage{}, errors.New("invalid activation summary")
|
||
}
|
||
}
|
||
return out, nil
|
||
}
|
||
|
||
// GetWorkflowActivation 明确读取给定历史激活,Step仍为逻辑步骤当前视图,不能用它替代历史Activation。
|
||
func (c *Client) GetWorkflowActivation(ctx context.Context, id, key, activation string) (WorkflowActivationDetail, error) {
|
||
var out WorkflowActivationDetail
|
||
path, err := workflowActivationPath(id, key, activation)
|
||
if err != nil {
|
||
return out, err
|
||
}
|
||
if err = c.call(ctx, "GET", path, "", nil, &out); err != nil {
|
||
return WorkflowActivationDetail{}, err
|
||
}
|
||
if out.InstanceID != id || out.Step.Key != key || out.Activation.ID != activation || !validID(out.Step.ID) || out.Activation.StepID != out.Step.ID || out.Activation.Sequence == 0 || out.Revision == 0 {
|
||
return WorkflowActivationDetail{}, errors.New("activation detail identity mismatch")
|
||
}
|
||
return out, nil
|
||
}
|
||
|
||
// ListWorkflowPollRounds 只读取一个激活内的查询轮次;人工恢复的同一业务轮可分属不同激活。
|
||
func (c *Client) ListWorkflowPollRounds(ctx context.Context, id, key, activation string, in HistoryPageRequest) (WorkflowPollRoundPage, error) {
|
||
var out WorkflowPollRoundPage
|
||
path, err := workflowActivationPath(id, key, activation)
|
||
if err != nil {
|
||
return out, err
|
||
}
|
||
query, err := historyPageQuery(in)
|
||
if err != nil {
|
||
return out, err
|
||
}
|
||
if err = c.call(ctx, "GET", path+"/rounds"+query, "", nil, &out); err != nil {
|
||
return WorkflowPollRoundPage{}, err
|
||
}
|
||
if out.InstanceID != id || out.ActivationID != activation || out.Revision == 0 || out.Items == nil || !historyResponseSize(len(out.Items), in) {
|
||
return WorkflowPollRoundPage{}, errors.New("invalid poll round page")
|
||
}
|
||
for i, r := range out.Items {
|
||
if !validID(r.ID) || !validID(r.TaskID) || r.ActivationID != activation || r.Round == 0 || i > 0 && r.Round >= out.Items[i-1].Round {
|
||
return WorkflowPollRoundPage{}, errors.New("invalid poll round summary")
|
||
}
|
||
}
|
||
return out, nil
|
||
}
|
||
|
||
// ListWorkflowSignals 不携带信号正文;单条原始内容用GetWorkflowSignal读取。
|
||
func (c *Client) ListWorkflowSignals(ctx context.Context, id string, in HistoryPageRequest) (WorkflowSignalPage, error) {
|
||
var out WorkflowSignalPage
|
||
path, err := workflowSignalPath(id)
|
||
if err != nil {
|
||
return out, err
|
||
}
|
||
query, err := historyPageQuery(in)
|
||
if err != nil {
|
||
return out, err
|
||
}
|
||
if err = c.call(ctx, "GET", path+query, "", nil, &out); err != nil {
|
||
return WorkflowSignalPage{}, err
|
||
}
|
||
if out.WorkflowID != id || out.Revision == 0 || out.Items == nil || !historyResponseSize(len(out.Items), in) {
|
||
return WorkflowSignalPage{}, errors.New("invalid signal page")
|
||
}
|
||
for _, v := range out.Items {
|
||
if !validID(v.ID) || v.WorkflowID != id {
|
||
return WorkflowSignalPage{}, errors.New("signal summary identity mismatch")
|
||
}
|
||
}
|
||
return out, nil
|
||
}
|
||
|
||
// ListWorkflowSignalOperations 需要独立workflows:audit:read权限,只返回信号资源的操作审计摘要。
|
||
func (c *Client) ListWorkflowSignalOperations(ctx context.Context, id, signal string, in HistoryPageRequest) (WorkflowSignalOperationPage, error) {
|
||
var out WorkflowSignalOperationPage
|
||
path, err := workflowSignalPath(id, signal)
|
||
if err != nil {
|
||
return out, err
|
||
}
|
||
query, err := historyPageQuery(in)
|
||
if err != nil {
|
||
return out, err
|
||
}
|
||
if err = c.call(ctx, "GET", path+"/operations"+query, "", nil, &out); err != nil {
|
||
return WorkflowSignalOperationPage{}, err
|
||
}
|
||
if out.Items == nil || !historyResponseSize(len(out.Items), in) {
|
||
return WorkflowSignalOperationPage{}, errors.New("invalid signal operation page")
|
||
}
|
||
for _, v := range out.Items {
|
||
if !validID(v.ID) || v.WorkflowID != id || v.SignalID != signal {
|
||
return WorkflowSignalOperationPage{}, errors.New("signal operation identity mismatch")
|
||
}
|
||
}
|
||
return out, nil
|
||
}
|
||
func (c *Client) GetWorkflowSignalOperation(ctx context.Context, id, signal, operation string) (WorkflowSignalOperation, error) {
|
||
var out WorkflowSignalOperation
|
||
path, err := workflowSignalPath(id, signal)
|
||
if err != nil {
|
||
return out, err
|
||
}
|
||
if !validID(operation) {
|
||
return out, errors.New("invalid signal operation id")
|
||
}
|
||
if err = c.call(ctx, "GET", path+"/operations/"+operation, "", nil, &out); err != nil {
|
||
return WorkflowSignalOperation{}, err
|
||
}
|
||
if out.ID != operation || out.WorkflowID != id || out.SignalID != signal {
|
||
return WorkflowSignalOperation{}, errors.New("signal operation detail identity mismatch")
|
||
}
|
||
return out, nil
|
||
}
|