1
0
Fork 0
mirror of https://github.com/openstf/stf synced 2025-10-04 18:29:17 +02:00

Modify APIs from Aysnc -> Sync using timeout

This commit is contained in:
Vishal Banthia 2015-12-14 14:02:20 +09:00
parent d67d06a19f
commit a6266931ad
10 changed files with 354 additions and 239 deletions

View file

@ -874,6 +874,9 @@ program
.option('-c, --connect-push <endpoint>' .option('-c, --connect-push <endpoint>'
, 'push endpoint' , 'push endpoint'
, cliutil.list) , cliutil.list)
.option('-u, --connect-sub <endpoint>'
, 'sub endpoint'
, cliutil.list)
.action(function(options) { .action(function(options) {
if (!options.secret) { if (!options.secret) {
this.missingArgument('--secret') this.missingArgument('--secret')
@ -881,6 +884,9 @@ program
if (!options.connectPush) { if (!options.connectPush) {
this.missingArgument('--connect-push') this.missingArgument('--connect-push')
} }
if (!options.connectSub) {
this.missingArgument('--connect-sub')
}
require('./units/api')({ require('./units/api')({
port: options.port port: options.port
@ -888,6 +894,7 @@ program
, secret: options.secret , secret: options.secret
, endpoints: { , endpoints: {
push: options.connectPush push: options.connectPush
, sub: options.connectSub
} }
}) })
}) })
@ -1338,6 +1345,7 @@ program
, '--port', options.apiPort , '--port', options.apiPort
, '--secret', options.authSecret , '--secret', options.authSecret
, '--connect-push', options.bindAppPull , '--connect-push', options.bindAppPull
, '--connect-sub', options.bindAppPub
]) ])
// websocket // websocket
, procutil.fork(__filename, [ , procutil.fork(__filename, [

View file

@ -152,7 +152,7 @@ dbapi.saveDeviceInitialState = function(serial, device) {
, ready: false , ready: false
, reverseForwards: [] , reverseForwards: []
, remoteConnect: false , remoteConnect: false
, remoteDebugUrl: null , remoteConnectUrl: null
} }
return db.run(r.table('devices').get(serial).update(data)) return db.run(r.table('devices').get(serial).update(data))
.then(function(stats) { .then(function(stats) {
@ -167,14 +167,14 @@ dbapi.saveDeviceInitialState = function(serial, device) {
dbapi.setDeviceConnectUrl = function(serial, url) { dbapi.setDeviceConnectUrl = function(serial, url) {
return db.run(r.table('devices').get(serial).update({ return db.run(r.table('devices').get(serial).update({
remoteDebugUrl: url remoteConnectUrl: url
, remoteConnect: true , remoteConnect: true
})) }))
} }
dbapi.unsetDeviceConnectUrl = function(serial, url) { dbapi.unsetDeviceConnectUrl = function(serial, url) {
return db.run(r.table('devices').get(serial).update({ return db.run(r.table('devices').get(serial).update({
remoteDebugUrl: null remoteConnectUrl: null
, remoteConnect: false , remoteConnect: false
})) }))
} }

View file

@ -49,24 +49,22 @@ function getDeviceBySerial(req, res) {
dbapi.loadDevice(serial) dbapi.loadDevice(serial)
.then(function(device) { .then(function(device) {
if (device) { if (!device) {
datautil.normalize(device, req.user) return res.status(404).json({
if(fields) {
device = _.pick(device, fields.split(','))
}
res.json({
success: true
, device: device
})
}
else {
res.status(404).json({
success: false success: false
, description: 'Device not found' , description: 'Device not found'
}) })
} }
datautil.normalize(device, req.user)
if(fields) {
device = _.pick(device, fields.split(','))
}
res.json({
success: true
, device: device
})
}) })
.catch(function(err) { .catch(function(err) {
log.error('Failed to load device "%s": ', req.params.serial, err.stack) log.error('Failed to load device "%s": ', req.params.serial, err.stack)

View file

@ -1,13 +1,16 @@
var util = require('util') var util = require('util')
var Promise = require('bluebird')
var _ = require('lodash') var _ = require('lodash')
var Promise = require('bluebird')
var uuid = require('node-uuid')
var dbapi = require('../../../db/api') var dbapi = require('../../../db/api')
var logger = require('../../../util/logger') var logger = require('../../../util/logger')
var datautil = require('../../../util/datautil') var datautil = require('../../../util/datautil')
var deviceutil = require('../../../util/deviceutil')
var wire = require('../../../wire') var wire = require('../../../wire')
var wireutil = require('../../../wire/util') var wireutil = require('../../../wire/util')
var wirerouter = require('../../../wire/router')
var log = logger.createLogger('api:controllers:user') var log = logger.createLogger('api:controllers:user')
@ -66,32 +69,29 @@ function getUserDeviceBySerial(req, res) {
dbapi.loadDevice(serial) dbapi.loadDevice(serial)
.then(function(device) { .then(function(device) {
if (device) { if (!device) {
datautil.normalize(device, req.user) return res.status(404).json({
if (device.owner && device.owner.email === req.user.email) {
if(fields) {
device = _.pick(device, fields.split(','))
}
res.json({
success: true
, device: device
})
}
else {
res.status(401).json({
success: false
, description: 'Device is not owned by you'
})
}
}
else {
res.status(404).json({
success: false success: false
, description: 'Device not found' , description: 'Device not found'
}) })
} }
datautil.normalize(device, req.user)
if (!deviceutil.isOwnedByUser(device, req.user)) {
return res.status(403).json({
success: false
, description: 'Device is not owned by you'
})
}
if(fields) {
device = _.pick(device, fields.split(','))
}
res.json({
success: true
, device: device
})
}) })
.catch(function(err) { .catch(function(err) {
log.error('Failed to load device "%s": ', req.params.serial, err.stack) log.error('Failed to load device "%s": ', req.params.serial, err.stack)
@ -107,55 +107,71 @@ function addUserDevice(req, res) {
dbapi.loadDevice(serial) dbapi.loadDevice(serial)
.then(function(device) { .then(function(device) {
if (device) { if (!device) {
datautil.normalize(device, req.user) return res.status(404).json({
if(device.present && device.ready && !device.using && !device.owner) {
var requirements = {
'serial': {
'value': serial,
'match': 'exact'
}
}
req.options.push.send([
device.channel
, wireutil.envelope(
new wire.GroupMessage(
new wire.OwnerMessage(
req.user.email
, req.user.name
, req.user.group
)
, timeout
, wireutil.toDeviceRequirements(requirements)
)
)
])
res.status(202).json({
success: true
, description: 'Device Add request is accepted. Check if device is successfully added using pollingUrl'
, pollingUrl: util.format('%s://%s%s/user/devices/%s'
, req.protocol
, req.get('host')
, req.swagger.operation.api.basePath
, serial
)
})
} else {
res.status(401).json({
success: false
, description: 'Device is being used or not available'
})
}
} else {
res.status(404).json({
success: false success: false
, description: 'Bad device serial' , description: 'Device not found'
}) })
} }
datautil.normalize(device, req.user)
if (!deviceutil.isAddable(device, req.user)) {
return res.status(403).json({
success: false
, description: 'Device is being used or not available'
})
}
// Timer will be called if no JoinGroupMessage is received till 5 seconds
var responseTimer = setTimeout(function() {
req.options.channelRouter.removeListener(wireutil.global, messageListener)
return res.status(504).json({
success: false
, description: 'Device is not responding'
})
}, 5000)
var messageListener = wirerouter()
.on(wire.JoinGroupMessage, function(channel, message) {
if (message.serial === serial && message.owner.email === req.user.email) {
clearTimeout(responseTimer)
req.options.channelRouter.removeListener(wireutil.global, messageListener)
return res.json({
success: true
, description: 'Device successfully added'
})
}
})
.handler()
req.options.channelRouter.on(wireutil.global, messageListener)
req.options.push.send([
device.channel
, wireutil.envelope(
new wire.GroupMessage(
new wire.OwnerMessage(
req.user.email
, req.user.name
, req.user.group
)
, timeout
, wireutil.toDeviceRequirements({
'serial': {
'value': serial
, 'match': 'exact'
}
})
)
)
])
})
.catch(function(err) {
log.error('Failed to load device "%s": ', req.params.serial, err.stack)
res.status(500).json({
success: false
})
}) })
} }
@ -164,49 +180,66 @@ function deleteUserDeviceBySerial(req, res) {
dbapi.loadDevice(serial) dbapi.loadDevice(serial)
.then(function(device) { .then(function(device) {
if (device) { if (!device) {
datautil.normalize(device, req.user) return res.status(404).json({
if(device.using && device.owner.email == req.user.email) {
var requirements = {
'serial': {
'value': serial,
'match': 'exact'
}
}
req.options.push.send([
device.channel
, wireutil.envelope(
new wire.UngroupMessage(
wireutil.toDeviceRequirements(requirements)
)
)
])
res.status(202).json({
success: true
, description: 'Device Release request is accepted. Check if device is successfully removed using pollingUrl'
, pollingUrl: util.format('%s://%s%s/user/devices/%s'
, req.protocol
, req.get('host')
, req.swagger.operation.api.basePath
, serial
)
})
} else {
res.status(401).json({
success: false
, description: 'You cannot kick this device'
})
}
} else {
res.status(404).json({
success: false success: false
, description: 'Bad device serial' , description: 'Device not found'
}) })
} }
datautil.normalize(device, req.user)
if (!deviceutil.isOwnedByUser(device, req.user)) {
return res.status(403).json({
success: false
, description: 'You cannot release this device. Not owned by you'
})
}
// Timer will be called if no JoinGroupMessage is received till 5 seconds
var responseTimer = setTimeout(function() {
req.options.channelRouter.removeListener(wireutil.global, messageListener)
return res.status(504).json({
success: false
, description: 'Device is not responding'
})
}, 5000)
var messageListener = wirerouter()
.on(wire.LeaveGroupMessage, function(channel, message) {
if (message.serial === serial && message.owner.email === req.user.email) {
clearTimeout(responseTimer)
req.options.channelRouter.removeListener(wireutil.global, messageListener)
return res.json({
success: true
, description: 'Device successfully removed'
})
}
})
.handler()
req.options.channelRouter.on(wireutil.global, messageListener)
req.options.push.send([
device.channel
, wireutil.envelope(
new wire.UngroupMessage(
wireutil.toDeviceRequirements({
'serial': {
'value': serial
, 'match': 'exact'
}
})
)
)
])
})
.catch(function(err) {
log.error('Failed to load device "%s": ', req.params.serial, err.stack)
res.status(500).json({
success: false
})
}) })
} }
@ -215,41 +248,58 @@ function remoteConnectUserDeviceBySerial(req, res) {
dbapi.loadDevice(serial) dbapi.loadDevice(serial)
.then(function(device) { .then(function(device) {
if (device) { if (!device) {
datautil.normalize(device, req.user) return res.status(404).json({
if (device.present && device.ready && device.using && device.owner.email === req.user.email) {
req.options.push.send([
device.channel
, wireutil.envelope(
new wire.ConnectStartMessage()
)
])
res.status(202).json({
success: true
, description: 'Device Connect request is accepted. Check if device is successfully connected using pollingUrl'
, pollingUrl: util.format('%s://%s%s/user/devices/%s'
, req.protocol
, req.get('host')
, req.swagger.operation.api.basePath
, serial
)
})
}
else {
res.status(401).json({
success: false
, description: 'Device is not owned by you or is not available'
})
}
}
else {
res.status(404).json({
success: false success: false
, description: 'Device not found' , description: 'Device not found'
}) })
} }
datautil.normalize(device, req.user)
if (!deviceutil.isOwnedByUser(device, req.user)) {
return res.status(403).json({
success: false
, description: 'Device is not owned by you or is not available'
})
}
var responseChannel = 'txn_' + uuid.v4()
req.options.sub.subscribe(responseChannel)
// Timer will be called if no JoinGroupMessage is received till 5 seconds
var timer = setTimeout(function() {
req.options.channelRouter.removeListener(responseChannel, messageListener)
req.options.sub.unsubscribe(responseChannel)
return res.status(504).json({
success: false
, description: 'Device is not responding'
})
}, 5000)
var messageListener = wirerouter()
.on(wire.ConnectStartedMessage, function(channel, message) {
if (message.serial === serial) {
clearTimeout(timer)
req.options.sub.unsubscribe(responseChannel)
req.options.channelRouter.removeListener(responseChannel, messageListener)
return res.json({
success: true
, remoteConnectUrl: message.url
})
}
})
.handler()
req.options.channelRouter.on(responseChannel, messageListener)
req.options.push.send([
device.channel
, wireutil.transaction(
responseChannel
, new wire.ConnectStartMessage()
)
])
}) })
.catch(function(err) { .catch(function(err) {
log.error('Failed to load device "%s": ', req.params.serial, err.stack) log.error('Failed to load device "%s": ', req.params.serial, err.stack)
@ -264,41 +314,59 @@ function remoteDisconnectUserDeviceBySerial(req, res) {
dbapi.loadDevice(serial) dbapi.loadDevice(serial)
.then(function(device) { .then(function(device) {
if (device) {
datautil.normalize(device, req.user)
if (device.present && device.ready && device.using && device.owner.email == req.user.email) { if (!device) {
req.options.push.send([ return res.status(404).json({
device.channel
, wireutil.envelope(
new wire.ConnectStopMessage()
)
])
res.status(202).json({
success: true
, description: 'Device Disonnect request is accepted. Check if device is successfully disconnected using pollingUrl'
, pollingUrl: util.format('%s://%s%s/user/devices/%s'
, req.protocol
, req.get('host')
, req.swagger.operation.api.basePath
, serial
)
})
}
else {
res.status(401).json({
success: false
, description: 'Device is not owned by you or is not available'
})
}
}
else {
res.status(404).json({
success: false success: false
, description: 'Device not found' , description: 'Device not found'
}) })
} }
datautil.normalize(device, req.user)
if (!deviceutil.isOwnedByUser(device, req.user)) {
return res.status(403).json({
success: false
, description: 'Device is not owned by you or is not available'
})
}
var responseChannel = 'txn_' + uuid.v4()
req.options.sub.subscribe(responseChannel)
// Timer will be called if no JoinGroupMessage is received till 5 seconds
var timer = setTimeout(function() {
req.options.channelRouter.removeListener(responseChannel, messageListener)
req.options.sub.unsubscribe(responseChannel)
return res.status(504).json({
success: false
, description: 'Device is not responding'
})
}, 5000)
var messageListener = wirerouter()
.on(wire.ConnectStoppedMessage, function(channel, message) {
if (message.serial === serial) {
clearTimeout(timer)
req.options.sub.unsubscribe(responseChannel)
req.options.channelRouter.removeListener(responseChannel, messageListener)
return res.json({
success: true
, description: 'Device remote disconnected successfully'
})
}
})
.handler()
req.options.channelRouter.on(responseChannel, messageListener)
req.options.push.send([
device.channel
, wireutil.transaction(
responseChannel
, new wire.ConnectStopMessage()
)
])
}) })
.catch(function(err) { .catch(function(err) {
log.error('Failed to load device "%s": ', req.params.serial, err.stack) log.error('Failed to load device "%s": ', req.params.serial, err.stack)

View file

@ -1,5 +1,6 @@
var http = require('http') var http = require('http')
var path = require('path') var path = require('path')
var events = require('events')
var express = require('express') var express = require('express')
var SwaggerExpress = require('swagger-express-mw') var SwaggerExpress = require('swagger-express-mw')
@ -11,11 +12,13 @@ var logger = require('../../util/logger')
var zmqutil = require('../../util/zmqutil') var zmqutil = require('../../util/zmqutil')
var srv = require('../../util/srv') var srv = require('../../util/srv')
var lifecycle = require('../../util/lifecycle') var lifecycle = require('../../util/lifecycle')
var wireutil = require('../../wire/util')
module.exports = function(options) { module.exports = function(options) {
var log = logger.createLogger('api') var log = logger.createLogger('api')
, app = express() , app = express()
, server = http.createServer(app) , server = http.createServer(app)
, channelRouter = new events.EventEmitter()
var push = zmqutil.socket('push') var push = zmqutil.socket('push')
Promise.map(options.endpoints.push, function(endpoint) { Promise.map(options.endpoints.push, function(endpoint) {
@ -27,18 +30,47 @@ module.exports = function(options) {
}) })
}) })
}) })
.catch(function(err) { .catch(function(err) {w
log.fatal('Unable to connect to push endpoint', err) log.fatal('Unable to connect to push endpoint', err)
lifecycle.fatal() lifecycle.fatal()
}) })
// Input
var sub = zmqutil.socket('sub')
Promise.map(options.endpoints.sub, function(endpoint) {
return srv.resolve(endpoint).then(function(records) {
return srv.attempt(records, function(record) {
log.info('Receiving input from "%s"', record.url)
sub.connect(record.url)
return Promise.resolve(true)
})
})
})
.catch(function(err) {
log.fatal('Unable to connect to sub endpoint', err)
lifecycle.fatal()
})
// Establish always-on channels
;[wireutil.global].forEach(function(channel) {
log.info('Subscribing to permanent channel "%s"', channel)
sub.subscribe(channel)
})
sub.on('message', function(channel, data) {
channelRouter.emit(channel.toString(), channel, data)
})
// Swagger Express Config
var config = { var config = {
appRoot: __dirname appRoot: __dirname
, swaggerFile: path.resolve(__dirname, 'swagger', 'api_v1.yaml') , swaggerFile: path.resolve(__dirname, 'swagger', 'api_v1.yaml')
}; };
SwaggerExpress.create(config, function(err, swaggerExpress) { SwaggerExpress.create(config, function(err, swaggerExpress) {
if (err) { throw err; } if (err) {
throw err
}
swaggerExpress.register(app); swaggerExpress.register(app);
}) })
@ -47,6 +79,8 @@ module.exports = function(options) {
app.use(function(req, res, next) { app.use(function(req, res, next) {
var reqOptions = _.merge(options, { var reqOptions = _.merge(options, {
'push': push 'push': push
, 'sub': sub
, 'channelRouter': channelRouter
}) })
req.options = reqOptions req.options = reqOptions
@ -59,6 +93,17 @@ module.exports = function(options) {
, keys: [options.secret] , keys: [options.secret]
})) }))
lifecycle.observe(function() {
[push, sub].forEach(function(sock) {
try {
sock.close()
}
catch (err) {
// No-op
}
})
})
server.listen(options.port) server.listen(options.port)
log.info('Listening on port %d', options.port) log.info('Listening on port %d', options.port)
} }

View file

@ -46,7 +46,7 @@ paths:
/user/devices: /user/devices:
x-swagger-router-controller: user x-swagger-router-controller: user
get: get:
summary: List devices owned by current user summary: User Devices
description: The User Devices endpoint returns device list owner by current authorized user description: The User Devices endpoint returns device list owner by current authorized user
operationId: getUserDevices operationId: getUserDevices
tags: tags:
@ -70,22 +70,20 @@ paths:
- accessTokenAuth: [] - accessTokenAuth: []
post: post:
summary: Add a device to a user summary: Add a device to a user
description: The User Devices endpoint will request stf server for a new device. It will return request accepted if device is usable description: The User Devices endpoint will request stf server for a new device.
operationId: addUserDevice operationId: addUserDevice
tags: tags:
- user - user
parameters: parameters:
- name: devices - name: device
in: body in: body
description: Device to add description: Device to add
required: true required: true
schema: schema:
$ref: "#/definitions/AddUserDevicePayload" $ref: "#/definitions/AddUserDevicePayload"
responses: responses:
"202": "200":
description: Add User Device Request Status and polling Url description: Add User Device Status
schema:
$ref: "#/definitions/AddUserDeviceResponse"
default: default:
description: Unexpected Error description: Unexpected Error
schema: schema:
@ -95,8 +93,8 @@ paths:
/user/devices/{serial}: /user/devices/{serial}:
x-swagger-router-controller: user x-swagger-router-controller: user
get: get:
summary: Device Information summary: User Device
description: The device enpoint return information about device owned by user description: The devices enpoint return information about device owned by user
operationId: getUserDeviceBySerial operationId: getUserDeviceBySerial
tags: tags:
- user - user
@ -113,9 +111,9 @@ paths:
type: string type: string
responses: responses:
"200": "200":
description: Delete User Device Request Status and polling Url description: Device Information owned by user
schema: schema:
$ref: "#/definitions/DeleteUserDeviceBySerialResponse" $ref: "#/definitions/DeviceResponse"
default: default:
description: Unexpected Error description: Unexpected Error
schema: schema:
@ -123,7 +121,7 @@ paths:
security: security:
- accessTokenAuth: [] - accessTokenAuth: []
delete: delete:
summary: Release device from user summary: Delete User Device
description: The User Devices endpoint will request for device release from stf server. It will return request accepted if device is being used by current user description: The User Devices endpoint will request for device release from stf server. It will return request accepted if device is being used by current user
operationId: deleteUserDeviceBySerial operationId: deleteUserDeviceBySerial
tags: tags:
@ -135,8 +133,8 @@ paths:
required: true required: true
type: string type: string
responses: responses:
"202": "200":
description: Device Release Request Status description: Delete User Device Status
default: default:
description: Unexpected Error description: Unexpected Error
schema: schema:
@ -160,7 +158,7 @@ paths:
required: true required: true
type: string type: string
responses: responses:
"202": "200":
description: Remote Connect User Device Request Status description: Remote Connect User Device Request Status
schema: schema:
$ref: "#/definitions/RemoteConnectUserDeviceResponse" $ref: "#/definitions/RemoteConnectUserDeviceResponse"
@ -183,10 +181,8 @@ paths:
required: true required: true
type: string type: string
responses: responses:
"202": "200":
description: Remote Disonnect User Device Request Status description: Remote Disonnect User Device Request Status
schema:
$ref: "#/definitions/RemoteDisconnectUserDeviceResponse"
default: default:
description: Unexpected Error description: Unexpected Error
schema: schema:
@ -194,7 +190,7 @@ paths:
security: security:
- accessTokenAuth: [] - accessTokenAuth: []
/user/accessTokens: /user/accessTokens:
x-swagger-router-controller: token x-swagger-router-controller: user
get: get:
summary: Access Tokens summary: Access Tokens
description: The Access Tokens endpoints returns titles of all the valid access tokens description: The Access Tokens endpoints returns titles of all the valid access tokens
@ -298,35 +294,14 @@ definitions:
properties: properties:
device: device:
type: object type: object
AddUserDeviceResponse:
required:
- pollingUrl
properties:
pollingUrl:
type: string
DeleteUserDeviceBySerialResponse:
required:
- pollingUrl
properties:
pollingUrl:
type: string
RemoteDisconnectUserDeviceResponse:
required:
- pollingUrl
properties:
pollingUrl:
type: string
RemoteConnectUserDeviceResponse: RemoteConnectUserDeviceResponse:
required: required:
- pollingUrl - remoteConnectUrl
- serial
properties: properties:
pollingUrl: remoteConnectUrl:
type: string type: string
ErrorResponse: serial:
required:
- message
properties:
message:
type: string type: string
AddUserDevicePayload: AddUserDevicePayload:
description: payload object for adding device to user description: payload object for adding device to user
@ -339,7 +314,12 @@ definitions:
timeout: timeout:
description: Device timeout in ms. If device is kept idle for this period, it will be automatically disconnected. Default is provider group timeout description: Device timeout in ms. If device is kept idle for this period, it will be automatically disconnected. Default is provider group timeout
type: integer type: integer
ErrorResponse:
required:
- message
properties:
message:
type: string
securityDefinitions: securityDefinitions:
accessTokenAuth: accessTokenAuth:
type: apiKey type: apiKey

View file

@ -142,15 +142,16 @@ module.exports = syrup.serial()
channel channel
, reply.okay(url) , reply.okay(url)
]) ])
// Update DB // Update DB
push.send([ push.send([
wireutil.global channel
, wireutil.envelope(new wire.ConnectStartedMessage( , wireutil.envelope(new wire.ConnectStartedMessage(
options.serial options.serial
, url , url
)) ))
]) ])
log.info('Remote Connect Started for device "%s" at "%s"', options.serial, url) log.important('Remote Connect Started for device "%s" at "%s"', options.serial, url)
}) })
.catch(function(err) { .catch(function(err) {
log.error('Unable to start remote connect service', err.stack) log.error('Unable to start remote connect service', err.stack)
@ -170,12 +171,12 @@ module.exports = syrup.serial()
]) ])
// Update DB // Update DB
push.send([ push.send([
wireutil.global channel
, wireutil.envelope(new wire.ConnectStoppedMessage( , wireutil.envelope(new wire.ConnectStoppedMessage(
options.serial options.serial
)) ))
]) ])
log.info('Remote Connect Stopped for device "%s"', options.serial) log.important('Remote Connect Stopped for device "%s"', options.serial)
}) })
.catch(function(err) { .catch(function(err) {
log.error('Failed to stop connect service', err.stack) log.error('Failed to stop connect service', err.stack)

View file

@ -167,9 +167,11 @@ module.exports = function(options) {
}) })
.on(wire.ConnectStartedMessage, function(channel, message, data) { .on(wire.ConnectStartedMessage, function(channel, message, data) {
dbapi.setDeviceConnectUrl(message.serial, message.url) dbapi.setDeviceConnectUrl(message.serial, message.url)
appDealer.send([channel, data])
}) })
.on(wire.ConnectStoppedMessage, function(channel, message, data) { .on(wire.ConnectStoppedMessage, function(channel, message, data) {
dbapi.unsetDeviceConnectUrl(message.serial) dbapi.unsetDeviceConnectUrl(message.serial)
appDealer.send([channel, data])
}) })
.on(wire.JoinGroupMessage, function(channel, message, data) { .on(wire.JoinGroupMessage, function(channel, message, data) {
dbapi.setDeviceOwner(message.serial, message.owner) dbapi.setDeviceOwner(message.serial, message.owner)

View file

@ -59,7 +59,7 @@ datautil.applyOwnerOnlyInfo = function(device, user) {
if (device.owner && device.owner.email === user.email) { if (device.owner && device.owner.email === user.email) {
} else { } else {
device.remoteConnect = false device.remoteConnect = false
device.remoteDebugUrl = null device.remoteConnectUrl = null
} }
} }

13
lib/util/deviceutil.js Normal file
View file

@ -0,0 +1,13 @@
var logger = require('./logger')
var log = logger.createLogger('util:deviceutil')
var deviceutil = module.exports = Object.create(null)
deviceutil.isOwnedByUser = function(device, user) {
return device.present && device.ready && device.owner && device.owner.email === user.email && device.using
}
deviceutil.isAddable = function(device, user) {
return device.present && device.ready && !device.using && !device.owner
}