Files
orbit/sdk/go/workflow_history.go

174 lines
6.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}