@@ -21,6 +21,7 @@ import (
21
21
"encoding/json"
22
22
"fmt"
23
23
"strings"
24
+ "time"
24
25
25
26
"github.com/skydive-project/skydive/js"
26
27
@@ -30,42 +31,56 @@ import (
30
31
"github.com/skydive-project/skydive/graffiti/graph/traversal"
31
32
)
32
33
33
- // RegisterAPIServer exports Go functions required by the API
34
- // to run inside the JS VM
35
- func RegisterAPIServer (r * js.Runtime , g * graph.Graph , gremlinParser * traversal.GremlinTraversalParser , server * Server ) {
34
+ // NewWorkflowRuntime returns a new Workflow runtime
35
+ func NewWorkflowRuntime (g * graph.Graph , tr * traversal.GremlinTraversalParser , server * Server ) (* js.Runtime , error ) {
36
+ runtime , err := js .NewRuntime ()
37
+ if err != nil {
38
+ return nil , err
39
+ }
40
+ runtime .Start ()
41
+
36
42
queryGremlin := func (query string ) otto.Value {
37
- ts , err := gremlinParser .Parse (strings .NewReader (query ))
43
+ ts , err := tr .Parse (strings .NewReader (query ))
38
44
if err != nil {
39
- return r .MakeCustomError ("ParseError" , err .Error ())
45
+ return runtime .MakeCustomError ("ParseError" , err .Error ())
40
46
}
41
47
42
48
result , err := ts .Exec (g , false )
43
49
if err != nil {
44
- return r .MakeCustomError ("ExecuteError" , err .Error ())
50
+ return runtime .MakeCustomError ("ExecuteError" , err .Error ())
45
51
}
46
52
47
53
source , err := result .MarshalJSON ()
48
54
if err != nil {
49
- return r .MakeCustomError ("MarshalError" , err .Error ())
55
+ return runtime .MakeCustomError ("MarshalError" , err .Error ())
50
56
}
51
57
52
- r , _ := r .ToValue (string (source ))
58
+ r , _ := runtime .ToValue (string (source ))
53
59
return r
54
60
}
55
61
56
- r .Set ("Gremlin" , func (call otto.FunctionCall ) otto.Value {
62
+ runtime .Set ("sleep" , func (call otto.FunctionCall ) otto.Value {
63
+ if len (call .ArgumentList ) != 1 || ! call .Argument (0 ).IsNumber () {
64
+ return runtime .MakeCustomError ("MissingArgument" , "Sleep requires a number parameter" )
65
+ }
66
+ t , _ := call .Argument (0 ).ToInteger ()
67
+ time .Sleep (time .Duration (t ) * time .Millisecond )
68
+ return otto .NullValue ()
69
+ })
70
+
71
+ runtime .Set ("Gremlin" , func (call otto.FunctionCall ) otto.Value {
57
72
if len (call .ArgumentList ) < 1 || ! call .Argument (0 ).IsString () {
58
- return r .MakeCustomError ("MissingQueryArgument" , "Gremlin requires a string parameter" )
73
+ return runtime .MakeCustomError ("MissingQueryArgument" , "Gremlin requires a string parameter" )
59
74
}
60
75
61
76
query := call .Argument (0 ).String ()
62
77
63
78
return queryGremlin (query )
64
79
})
65
80
66
- r .Set ("request" , func (call otto.FunctionCall ) otto.Value {
81
+ runtime .Set ("request" , func (call otto.FunctionCall ) otto.Value {
67
82
if len (call .ArgumentList ) < 3 || ! call .Argument (0 ).IsString () || ! call .Argument (1 ).IsString () || ! call .Argument (2 ).IsString () {
68
- return r .MakeCustomError ("WrongArguments" , "Import requires 3 string parameters" )
83
+ return runtime .MakeCustomError ("WrongArguments" , "Import requires 3 string parameters" )
69
84
}
70
85
71
86
url := call .Argument (0 ).String ()
@@ -74,15 +89,15 @@ func RegisterAPIServer(r *js.Runtime, g *graph.Graph, gremlinParser *traversal.G
74
89
75
90
subs := strings .Split (url , "/" ) // filepath.Base(url)
76
91
if len (subs ) < 3 {
77
- return r .MakeCustomError ("WrongArgument" , fmt .Sprintf ("Malformed URL %s" , url ))
92
+ return runtime .MakeCustomError ("WrongArgument" , fmt .Sprintf ("Malformed URL %s" , url ))
78
93
}
79
94
resource := subs [2 ]
80
95
81
96
// For topology query, we directly call the Gremlin engine
82
97
if resource == "topology" {
83
98
query := types.TopologyParam {}
84
99
if err := json .Unmarshal (data , & query ); err != nil {
85
- return r .MakeCustomError ("WrongArgument" , fmt .Sprintf ("Invalid query %s" , string (data )))
100
+ return runtime .MakeCustomError ("WrongArgument" , fmt .Sprintf ("Invalid query %s" , string (data )))
86
101
}
87
102
88
103
return queryGremlin (query .GremlinQuery )
@@ -98,17 +113,17 @@ func RegisterAPIServer(r *js.Runtime, g *graph.Graph, gremlinParser *traversal.G
98
113
case "POST" :
99
114
res := handler .New ()
100
115
if err := json .Unmarshal ([]byte (data ), res ); err != nil {
101
- return r .MakeCustomError ("UnmarshalError" , err .Error ())
116
+ return runtime .MakeCustomError ("UnmarshalError" , err .Error ())
102
117
}
103
118
if err := handler .Create (res ); err != nil {
104
- return r .MakeCustomError ("CreateError" , err .Error ())
119
+ return runtime .MakeCustomError ("CreateError" , err .Error ())
105
120
}
106
121
b , _ := json .Marshal (res )
107
122
content = string (b )
108
123
109
124
case "DELETE" :
110
125
if len (subs ) < 4 {
111
- return r .MakeCustomError ("WrongArgument" , "No ID specified" )
126
+ return runtime .MakeCustomError ("WrongArgument" , "No ID specified" )
112
127
}
113
128
handler .Delete (subs [3 ])
114
129
@@ -121,7 +136,7 @@ func RegisterAPIServer(r *js.Runtime, g *graph.Graph, gremlinParser *traversal.G
121
136
id := subs [3 ]
122
137
obj , found := handler .Get (id )
123
138
if ! found {
124
- return r .MakeCustomError ("NotFound" , fmt .Sprintf ("%s %s could not be found" , resource , id ))
139
+ return runtime .MakeCustomError ("NotFound" , fmt .Sprintf ("%s %s could not be found" , resource , id ))
125
140
}
126
141
b , _ := json .Marshal (obj )
127
142
content = string (b )
@@ -130,9 +145,11 @@ func RegisterAPIServer(r *js.Runtime, g *graph.Graph, gremlinParser *traversal.G
130
145
131
146
value , err := otto .ToValue (content )
132
147
if err != nil {
133
- return r .MakeCustomError ("WrongValue" , err .Error ())
148
+ return runtime .MakeCustomError ("WrongValue" , err .Error ())
134
149
}
135
150
136
151
return value
137
152
})
153
+
154
+ return runtime , nil
138
155
}
0 commit comments