Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Avatar for KuCalc : devops.
Download
50640 views
1
###
2
API for handling the messages described smc-util/message.coffee
3
4
AGPLv3, (c) 2017, SageMath, Inc.
5
###
6
7
async = require('async')
8
9
misc = require('smc-util/misc')
10
{defaults, required} = misc
11
12
messages = require('smc-util/message')
13
14
{Client} = require('../client')
15
16
class APIClient extends Client
17
push_to_client: (mesg, cb) =>
18
@emit 'push_to_client', mesg
19
cb?()
20
21
log = (name, logger) ->
22
if logger?
23
return (m...) -> logger.debug("API.#{name}: ", m...)
24
else
25
return ->
26
27
exports.http_message_api_v1 = (opts) ->
28
opts = defaults opts,
29
event : required
30
body : required
31
api_key : required
32
database : required
33
compute_server : required
34
ip_address : required
35
logger : undefined
36
cb : required
37
dbg = log('http_message_api_v1', opts.logger)
38
dbg("event=", opts.event, 'body=', opts.body)
39
40
f = messages[opts.event]
41
if not f?
42
opts.cb("unknown endpoint '#{opts.event}'")
43
return
44
45
if not messages.api_messages[opts.event]
46
opts.cb("endpoint '#{opts.event}' is not part of the HTTP API")
47
return
48
49
try
50
mesg = f(opts.body, true)
51
catch err
52
opts.cb("invalid parameters '#{err}'")
53
return
54
55
if mesg.event == 'query' and mesg.multi_response
56
otps.cb("multi_response queries aren't supported")
57
return
58
59
# client often expects id to be defined.
60
mesg.id ?= misc.uuid()
61
62
client = resp = undefined
63
async.series([
64
(cb) ->
65
get_client
66
api_key : opts.api_key
67
logger : opts.logger
68
database : opts.database
69
compute_server : opts.compute_server
70
ip_address : opts.ip_address
71
cb : (err, c) ->
72
client = c; cb(err)
73
(cb) ->
74
handle_message
75
client : client
76
mesg : mesg
77
logger : opts.logger
78
cb : (err, r) ->
79
resp = r; cb(err)
80
], (err) ->
81
opts.cb(err, resp)
82
)
83
84
auth_cache = {}
85
get_client = (opts) ->
86
opts = defaults opts,
87
api_key : required
88
logger : undefined
89
database : required
90
compute_server : required
91
ip_address : required
92
cb : required
93
dbg = log('get_client', opts.logger)
94
95
account_id = auth_cache[opts.api_key]
96
async.series([
97
(cb) ->
98
if account_id?
99
cb()
100
else
101
opts.database.get_account_with_api_key
102
api_key : opts.api_key
103
cb : (err, a) ->
104
if err
105
cb(err)
106
else
107
account_id = a
108
# cache api key being valid for a minute
109
auth_cache[opts.api_key] = account_id
110
setTimeout((->delete auth_cache[opts.api_key]), 60000)
111
cb()
112
], (err) ->
113
if err
114
opts.cb(err)
115
return
116
options =
117
logger : opts.logger
118
database : opts.database
119
compute_server : opts.compute_server
120
client = new APIClient(options)
121
client.ip_address = opts.ip_address
122
client.account_id = account_id
123
opts.cb(undefined, client)
124
)
125
126
handle_message = (opts) ->
127
opts = defaults opts,
128
mesg : required
129
client : required
130
logger : undefined
131
cb : required
132
dbg = log('handle_message', opts.logger)
133
dbg(opts.mesg, opts.client.id)
134
name = "mesg_#{opts.mesg.event}"
135
f = opts.client[name]
136
if not f?
137
opts.cb("unknown message event type '#{opts.mesg.event}'")
138
return
139
opts.client.once 'push_to_client', (mesg) ->
140
opts.cb(undefined, mesg)
141
f(opts.mesg)
142
143
144
145
146