...
1 package rollouts
2
3 import (
4 "encoding/json"
5 "fmt"
6 "reflect"
7 )
8
9
10
11
12
13 type RolloutPlan struct {
14 ID string
15 Name string
16 Description string
17
18 Initial []NodeKey
19 Nodes NodeMap
20 Edges []RolloutGraphEdge
21 Configuration json.RawMessage
22
23
24
25
26 }
27
28
29 type RolloutPlanJSON struct {
30 ID string `json:"id,omitempty"`
31 Name string `json:"name"`
32 Description string `json:"description"`
33 Initial []NodeKey `json:"initial"`
34 Nodes []BaseNodeJSON `json:"nodes"`
35 Edges []RolloutGraphEdge `json:"edges"`
36 }
37
38 func (p *RolloutPlan) UnmarshalJSON(data []byte) error {
39
40 planJSON := &RolloutPlanJSON{}
41 err := json.Unmarshal(data, planJSON)
42 if err != nil {
43 return fmt.Errorf("failed to unmarshal rollout graph payload: %v", err)
44 }
45
46
47 p.ID = planJSON.ID
48
49
50 p.Name = planJSON.Name
51
52
53 p.Description = planJSON.Description
54
55
56 p.Nodes = make(map[NodeKey]RolloutGraphNode, len(planJSON.Nodes))
57 for _, n := range planJSON.Nodes {
58 node, err := UnmarshalRolloutGraphNode(n)
59 if err != nil {
60 return err
61 }
62 p.Nodes[node.GetKey()] = node
63 }
64
65
66 p.Edges = make([]RolloutGraphEdge, len(planJSON.Edges))
67 for i, edge := range planJSON.Edges {
68
69 p.Edges[i] = RolloutGraphEdge{To: edge.To, From: edge.From}
70 toNode, found := p.Nodes[edge.To]
71 if !found {
72 return fmt.Errorf("node key %s was stated in edge but not in nodes", edge.To)
73 }
74 fromNode, found := p.Nodes[edge.From]
75 if !found {
76 return fmt.Errorf("node key %s was stated in edge but not in nodes", edge.From)
77 }
78 toNode.AddDependency(fromNode)
79 fromNode.AddNext(toNode)
80 }
81
82
83 p.Initial = planJSON.Initial
84
85 return nil
86 }
87
88 func (p *RolloutPlan) MarshalJSON() ([]byte, error) {
89
90 nodes := make([]BaseNodeJSON, len(p.Nodes))
91 i := 0
92 for _, node := range p.Nodes {
93 data, err := json.Marshal(node)
94 if err != nil {
95 return nil, fmt.Errorf("failed to marshal node: %v", err)
96 }
97 baseNodeJSON := BaseNodeJSON{
98
99
100 NodeType: reflect.Indirect(reflect.ValueOf(node)).Type().Name(),
101 Data: data,
102 }
103 nodes[i] = baseNodeJSON
104 i++
105 }
106
107
108 edges := make([]RolloutGraphEdge, len(p.Edges))
109 copy(edges, p.Edges)
110
111 jsonData := &RolloutGraphJSON{
112 Nodes: nodes,
113 Edges: edges,
114 }
115
116 return json.Marshal(jsonData)
117 }
118
119 func NewRolloutPlanFromJSON(data json.RawMessage) (RolloutPlan, error) {
120 plan := &RolloutPlan{}
121 err := json.Unmarshal(data, plan)
122 if err != nil {
123 return *plan, err
124 }
125 return *plan, nil
126 }
127
View as plain text