mirror of
https://github.com/certimate-go/certimate.git
synced 2026-06-22 21:05:48 +08:00
304 lines
7.3 KiB
Go
304 lines
7.3 KiB
Go
package engine
|
|
|
|
import (
|
|
"fmt"
|
|
"slices"
|
|
"strconv"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type VariableState struct {
|
|
Scope string // 零值时表示全局的,否则表示指定节点的
|
|
Key string
|
|
Value any
|
|
ValueType string
|
|
}
|
|
|
|
func (s VariableState) ValueString() string {
|
|
switch s.ValueType {
|
|
case "string":
|
|
return fmt.Sprintf("%s", s.Value)
|
|
case "number":
|
|
return fmt.Sprintf("%d", s.Value)
|
|
case "boolean":
|
|
return strconv.FormatBool(s.Value.(bool))
|
|
case "datetime":
|
|
valueAsTime := s.Value.(time.Time)
|
|
if valueAsTime.IsZero() {
|
|
return "-"
|
|
}
|
|
return valueAsTime.Format(time.RFC3339)
|
|
default:
|
|
return fmt.Sprintf("[%s]%v", s.ValueType, s.Value)
|
|
}
|
|
}
|
|
|
|
type VariableManager interface {
|
|
All() []VariableState
|
|
Erase()
|
|
|
|
Add(entry VariableState)
|
|
Set(name string, value any, valueType string)
|
|
SetScoped(scope string, name string, value any, valueType string)
|
|
Get(name string) (*VariableState, bool)
|
|
GetScoped(scope string, key string) (*VariableState, bool)
|
|
Take(key string) (*VariableState, bool)
|
|
TakeScoped(scope string, key string) (*VariableState, bool)
|
|
Remove(key string) bool
|
|
RemoveScoped(scope string, key string) bool
|
|
}
|
|
|
|
type variableManager struct {
|
|
statesMtx sync.RWMutex
|
|
states []VariableState
|
|
}
|
|
|
|
var _ VariableManager = (*variableManager)(nil)
|
|
|
|
func (m *variableManager) All() []VariableState {
|
|
m.statesMtx.RLock()
|
|
defer m.statesMtx.RUnlock()
|
|
|
|
if m.states == nil {
|
|
return make([]VariableState, 0)
|
|
}
|
|
|
|
return slices.Clone(m.states)
|
|
}
|
|
|
|
func (m *variableManager) Erase() {
|
|
m.statesMtx.Lock()
|
|
defer m.statesMtx.Unlock()
|
|
|
|
m.states = make([]VariableState, 0)
|
|
}
|
|
|
|
func (m *variableManager) Add(state VariableState) {
|
|
m.statesMtx.Lock()
|
|
defer m.statesMtx.Unlock()
|
|
|
|
if m.states == nil {
|
|
m.states = make([]VariableState, 0)
|
|
}
|
|
|
|
for i, item := range m.states {
|
|
if item.Scope == state.Scope && item.Key == state.Key {
|
|
m.states[i] = state
|
|
return
|
|
}
|
|
}
|
|
m.states = append(m.states, state)
|
|
}
|
|
|
|
func (m *variableManager) Set(key string, value any, valueType string) {
|
|
m.SetScoped("", key, value, valueType)
|
|
}
|
|
|
|
func (m *variableManager) SetScoped(scope string, key string, value any, valueType string) {
|
|
m.Add(VariableState{Scope: scope, Key: key, Value: value, ValueType: valueType})
|
|
}
|
|
|
|
func (m *variableManager) Get(key string) (*VariableState, bool) {
|
|
return m.GetScoped("", key)
|
|
}
|
|
|
|
func (m *variableManager) GetScoped(scope string, key string) (*VariableState, bool) {
|
|
m.statesMtx.RLock()
|
|
defer m.statesMtx.RUnlock()
|
|
|
|
if m.states == nil {
|
|
return nil, false
|
|
}
|
|
|
|
for _, item := range m.states {
|
|
if item.Scope == scope && item.Key == key {
|
|
return &item, true
|
|
}
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
func (m *variableManager) Take(key string) (*VariableState, bool) {
|
|
return m.TakeScoped("", key)
|
|
}
|
|
|
|
func (m *variableManager) TakeScoped(scope string, key string) (*VariableState, bool) {
|
|
m.statesMtx.Lock()
|
|
defer m.statesMtx.Unlock()
|
|
|
|
if m.states == nil {
|
|
return nil, false
|
|
}
|
|
|
|
for i, item := range m.states {
|
|
if item.Scope == scope && item.Key == key {
|
|
m.states = slices.Delete(m.states, i, i+1)
|
|
return &item, true
|
|
}
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
func (m *variableManager) Remove(key string) bool {
|
|
return m.RemoveScoped("", key)
|
|
}
|
|
|
|
func (m *variableManager) RemoveScoped(scope string, key string) bool {
|
|
_, ok := m.TakeScoped(scope, key)
|
|
return ok
|
|
}
|
|
|
|
func newVariableManager() VariableManager {
|
|
return &variableManager{
|
|
states: make([]VariableState, 0),
|
|
}
|
|
}
|
|
|
|
type InOutState struct {
|
|
NodeId string
|
|
Type string
|
|
Name string
|
|
Value any
|
|
ValueType string
|
|
Persistent bool
|
|
}
|
|
|
|
func (s InOutState) ValueString() string {
|
|
switch s.ValueType {
|
|
case "string":
|
|
return s.Value.(string)
|
|
case "number":
|
|
return fmt.Sprintf("%d", s.Value)
|
|
case "boolean":
|
|
return strconv.FormatBool(s.Value.(bool))
|
|
default:
|
|
return fmt.Sprintf("%v", s.Value)
|
|
}
|
|
}
|
|
|
|
type InOutManager interface {
|
|
All() []InOutState
|
|
Erase()
|
|
|
|
Add(state InOutState)
|
|
Set(nodeId string, stype string, name string, value any, valueType string, persistent bool)
|
|
Get(nodeId string, name string) (*InOutState, bool)
|
|
Take(nodeId string, name string) (*InOutState, bool)
|
|
Remove(nodeId string, name string) bool
|
|
}
|
|
|
|
type inoutManager struct {
|
|
statesMtx sync.RWMutex
|
|
states []InOutState
|
|
}
|
|
|
|
var _ InOutManager = (*inoutManager)(nil)
|
|
|
|
func (m *inoutManager) All() []InOutState {
|
|
m.statesMtx.RLock()
|
|
defer m.statesMtx.RUnlock()
|
|
|
|
if m.states == nil {
|
|
return make([]InOutState, 0)
|
|
}
|
|
|
|
return slices.Clone(m.states)
|
|
}
|
|
|
|
func (m *inoutManager) Erase() {
|
|
m.statesMtx.Lock()
|
|
defer m.statesMtx.Unlock()
|
|
|
|
m.states = make([]InOutState, 0)
|
|
}
|
|
|
|
func (m *inoutManager) Add(state InOutState) {
|
|
m.statesMtx.Lock()
|
|
defer m.statesMtx.Unlock()
|
|
|
|
if m.states == nil {
|
|
m.states = make([]InOutState, 0)
|
|
}
|
|
|
|
for i, item := range m.states {
|
|
if item.NodeId == state.NodeId && item.Name == state.Name {
|
|
m.states[i] = state
|
|
return
|
|
}
|
|
}
|
|
m.states = append(m.states, state)
|
|
}
|
|
|
|
func (m *inoutManager) Set(nodeId string, stype string, name string, value any, valueType string, persistent bool) {
|
|
m.Add(InOutState{NodeId: nodeId, Type: stype, Name: name, Value: value, ValueType: valueType, Persistent: persistent})
|
|
}
|
|
|
|
func (m *inoutManager) Get(nodeId string, name string) (*InOutState, bool) {
|
|
m.statesMtx.RLock()
|
|
defer m.statesMtx.RUnlock()
|
|
|
|
if m.states == nil {
|
|
return nil, false
|
|
}
|
|
|
|
for _, item := range m.states {
|
|
if item.NodeId == nodeId && item.Name == name {
|
|
return &item, true
|
|
}
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
func (m *inoutManager) Take(nodeId string, name string) (*InOutState, bool) {
|
|
m.statesMtx.Lock()
|
|
defer m.statesMtx.Unlock()
|
|
|
|
if m.states == nil {
|
|
return nil, false
|
|
}
|
|
|
|
for i, item := range m.states {
|
|
if item.NodeId == nodeId && item.Name == name {
|
|
m.states = slices.Delete(m.states, i, i+1)
|
|
return &item, true
|
|
}
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
func (m *inoutManager) Remove(nodeId string, name string) bool {
|
|
_, ok := m.Take(nodeId, name)
|
|
return ok
|
|
}
|
|
|
|
func newInOutManager() InOutManager {
|
|
return &inoutManager{
|
|
states: make([]InOutState, 0),
|
|
}
|
|
}
|
|
|
|
const (
|
|
stateIOTypeRef = "ref"
|
|
)
|
|
|
|
const (
|
|
stateVarKeyWorkflowId = "workflow.id" // ValueType: "string"
|
|
stateVarKeyWorkflowName = "workflow.name" // ValueType: "string"
|
|
stateVarKeyRunId = "run.id" // ValueType: "string"
|
|
stateVarKeyRunTrigger = "run.trigger" // ValueType: "string"
|
|
stateVarKeyNodeId = "node.id" // ValueType: "string"
|
|
stateVarKeyNodeName = "node.name" // ValueType: "string"
|
|
stateVarKeyNodeSkipped = "node.skipped" // ValueType: "boolean"
|
|
stateVarKeyErrorNodeId = "error.nodeId" // ValueType: "string"
|
|
stateVarKeyErrorNodeName = "error.nodeName" // ValueType: "string"
|
|
stateVarKeyErrorMessage = "error.message" // ValueType: "string"
|
|
stateVarKeyCertificateDomain = "certificate.domain" // ValueType: "string"
|
|
stateVarKeyCertificateDomains = "certificate.domains" // ValueType: "string"
|
|
stateVarKeyCertificateNotBefore = "certificate.notBefore" // ValueType: "datetime"
|
|
stateVarKeyCertificateNotAfter = "certificate.notAfter" // ValueType: "datetime"
|
|
stateVarKeyCertificateHoursLeft = "certificate.hoursLeft" // ValueType: "number"
|
|
stateVarKeyCertificateDaysLeft = "certificate.daysLeft" // ValueType: "number"
|
|
stateVarKeyCertificateValidity = "certificate.validity" // ValueType: "boolean"
|
|
)
|