-
Notifications
You must be signed in to change notification settings - Fork 19
/
summary.go
152 lines (129 loc) · 4.59 KB
/
summary.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package runs
import (
"encoding/json"
"github.com/nyaruka/goflow/assets"
"github.com/nyaruka/goflow/excellent/types"
"github.com/nyaruka/goflow/flows"
"github.com/nyaruka/goflow/utils"
)
// concrete run summary which might be stored on a trigger or event
type runSummary struct {
uuid flows.RunUUID
flow flows.Flow
contact *flows.Contact
status flows.RunStatus
results flows.Results
}
// creates a new run summary from the given run
func newRunSummaryFromRun(run flows.FlowRun) flows.RunSummary {
return &runSummary{
uuid: run.UUID(),
flow: run.Flow(),
contact: run.Contact().Clone(),
status: run.Status(),
results: run.Results().Clone(),
}
}
func (r *runSummary) UUID() flows.RunUUID { return r.uuid }
func (r *runSummary) Flow() flows.Flow { return r.flow }
func (r *runSummary) Contact() *flows.Contact { return r.contact }
func (r *runSummary) Status() flows.RunStatus { return r.status }
func (r *runSummary) Results() flows.Results { return r.results }
var _ flows.RunSummary = (*runSummary)(nil)
// wrapper for a run summary (concrete like runSummary or view of child run via interface)
type relatedRunContext struct {
run flows.RunSummary
}
func newRelatedRunContext(run flows.RunSummary) *relatedRunContext {
if utils.IsNil(run) {
return nil
}
return &relatedRunContext{run: run}
}
// RootContext returns the properties available in expressions for @parent and @child
func (c *relatedRunContext) Context(env utils.Environment) map[string]types.XValue {
var urns, fields types.XValue
if c.run.Contact() != nil {
urns = flows.ContextFunc(env, c.run.Contact().URNs().MapContext)
fields = flows.Context(env, c.run.Contact().Fields())
}
return map[string]types.XValue{
"__default__": types.NewXText(formatRunSummary(env, c.run)),
"uuid": types.NewXText(string(c.run.UUID())),
"run": flows.ContextFunc(env, c.RunContext), // deprecated to be removed in 13.1
"contact": flows.Context(env, c.run.Contact()),
"flow": flows.Context(env, c.run.Flow()),
"urns": urns,
"fields": fields,
"results": flows.Context(env, c.run.Results()),
"status": types.NewXText(string(c.run.Status())),
}
}
// Context returns the properties available in expressions. Run summaries expose a
// subset of the properties exposed by a real run.
func (c *relatedRunContext) RunContext(env utils.Environment) map[string]types.XValue {
return map[string]types.XValue{
"__default__": types.NewXText(formatRunSummary(env, c.run)),
"uuid": types.NewXText(string(c.run.UUID())),
"contact": flows.Context(env, c.run.Contact()),
"flow": flows.Context(env, c.run.Flow()),
"status": types.NewXText(string(c.run.Status())),
"results": flows.Context(env, c.run.Results()),
}
}
func formatRunSummary(env utils.Environment, run flows.RunSummary) string {
s := "@" + run.Flow().Name()
if run.Contact() != nil {
s = run.Contact().Format(env) + s
}
return s
}
//------------------------------------------------------------------------------------------
// JSON Encoding / Decoding
//------------------------------------------------------------------------------------------
type runSummaryEnvelope struct {
UUID flows.RunUUID `json:"uuid" validate:"uuid4"`
Flow *assets.FlowReference `json:"flow" validate:"required,dive"`
Contact json.RawMessage `json:"contact" validate:"required"`
Status flows.RunStatus `json:"status" validate:"required"`
Results flows.Results `json:"results"`
}
// ReadRunSummary reads a run summary from the given JSON
func ReadRunSummary(sessionAssets flows.SessionAssets, data json.RawMessage, missing assets.MissingCallback) (flows.RunSummary, error) {
var err error
e := runSummaryEnvelope{}
if err = utils.UnmarshalAndValidate(data, &e); err != nil {
return nil, err
}
run := &runSummary{
uuid: e.UUID,
status: e.Status,
results: e.Results,
}
// lookup the flow
if run.flow, err = sessionAssets.Flows().Get(e.Flow.UUID); err != nil {
return nil, err
}
// read the contact
if e.Contact != nil {
if run.contact, err = flows.ReadContact(sessionAssets, e.Contact, missing); err != nil {
return nil, err
}
}
return run, nil
}
// MarshalJSON marshals this run summary into JSON
func (r *runSummary) MarshalJSON() ([]byte, error) {
envelope := runSummaryEnvelope{}
var err error
envelope.UUID = r.uuid
envelope.Flow = r.flow.Reference()
envelope.Status = r.status
envelope.Results = r.results
if r.contact != nil {
if envelope.Contact, err = r.contact.MarshalJSON(); err != nil {
return nil, err
}
}
return json.Marshal(envelope)
}