Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(): registry support in core #88

Merged
merged 7 commits into from
Jan 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 14 additions & 101 deletions packages/cli/src/utils/registry/registry.js
Original file line number Diff line number Diff line change
@@ -1,131 +1,44 @@
import fs from 'fs'
import path from 'path'
import axios from 'axios'
import https from 'https'
import FormData from 'form-data'

import logger from '../debug'
import session from '../session'

const REGISTRY_TIMEOUT = 60000

const { debug } = logger('utils-registry')

class Registry {
constructor () {
debug('Registry.constructor')

const registryInstance = process.env.SYNCANO_SOCKET_REGISTRY_INSTANCE || 'socket-registry'
this.registryHost = `${registryInstance}.${session.ENDPOINT_HOST}`
this.registryHostUrl = `https://${this.registryHost}`

this.fileStorageHost = session.getHost()
this.fileStorageEndpoint = `/v2/instances/${registryInstance}/classes/storage/objects/`

if (session.project) {
this.installEndpoint = `/v2/instances/${session.project.instance}/sockets/install/`
this.installUrl = `https://${session.getHost()}${this.installEndpoint}`
}
}

getFullSocket (name, version) {
return this.searchSocketByName(name, version)
}

async searchSocketByName (name, version) {
debug(`searchSocketByName: ${name} (${version})`)
const response = await axios.request({
url: `https://${this.registryHost}/registry/get/`,
method: 'POST',
timeout: REGISTRY_TIMEOUT,
data: {
name,
version
},
headers: {
'X-Syncano-Account-Key': session.settings.account.getAuthKey()
}
})
return response.data
debug(`searchSocketByName: ${name} ${version}`)
return session.connection.registry.searchSocketByName(name, version)
}

static getSocket (socket) {
debug('getSocket')

const fileName = path.join(session.getBuildPath(), `${socket.name}.zip`)
const file = fs.createWriteStream(fileName)
return new Promise((resolve, reject) => {
https.get(socket.url, (response) => {
response.pipe(file)
file.on('finish', () => {
debug('Socket zip downloaded')
file.close(resolve)
})
})
})
const fileDescriptor = fs.createWriteStream(fileName)

return session.connection.registry.getSocket(socket.url, fileDescriptor)
}

async publishSocket (socketName, version) {
debug('publishSocket', socketName)
const response = await axios.request({
url: `${this.registryHostUrl}/registry/publish/`,
method: 'POST',
timeout: REGISTRY_TIMEOUT,
data: {
name: socketName,
version
},
headers: {
'X-Syncano-Account-Key': session.settings.account.getAuthKey()
}
})
return response.data
debug(`publishSocket: ${socketName}, ${version}`)
return session.connection.registry.publishSocket(socketName, version)
}

async searchSocketsByAll (keyword) {
const response = await axios.request({
url: `${this.registryHostUrl}/registry/search/`,
method: 'POST',
timeout: REGISTRY_TIMEOUT,
data: { keyword },
headers: {
'X-Syncano-Account-Key': session.settings.account.getAuthKey()
}
})
return response.data
debug(`searchSocketsByAll: ${keyword}`)
return session.connection.registry.searchSocketsByAll(keyword)
}

async submitSocket (socket) {
debug(`submitSocket: ${socket.name}`)
await socket.createPackageZip()

const form = new FormData()
form.append('file', fs.createReadStream(socket.getSocketZip()))
form.append('name', socket.spec.name)
form.append('description', socket.spec.description)
form.append('version', socket.spec.version)
form.append('keywords', JSON.stringify(socket.spec.keywords || []))
form.append('config', JSON.stringify(socket.getFullConfig()))

return new Promise((resolve, reject) => {
form.submit({
method: 'POST',
protocol: 'https:',
host: session.getHost(),
path: `${this.registryHostUrl}/registry/add/`,
headers: {
'X-Syncano-Account-Key': session.settings.account.getAuthKey()
}
}, (err, res) => {
if (err) {
debug('Error while uploading file', err)
reject(err)
}
res.on('data', (data) => {
debug('Upload done', data.toString())
resolve(data)
})
})
})
return session
.connection
.registry
.submitSocket(socket.spec, socket.getFullConfig(), socket.getSocketZip())
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/utils/sockets/sockets.js
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ class Socket {
async loadFromRegistry () {
debug(`loadFromRegistry: ${this.name}`)
const registry = new Registry()
const registrySocket = await registry.getFullSocket(this.name)
const registrySocket = await registry.searchSocketByName(this.name)

if (registrySocket.config) {
this.spec = registrySocket.config
Expand Down
1 change: 1 addition & 0 deletions packages/lib-js-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"node-fetch": "2.0.0-alpha.9"
},
"devDependencies": {
"@syncano/test-tools": "0.6.0",
"babel-cli": "^6.26.0",
"babel-eslint": "^8.0.1",
"babel-plugin-add-module-exports": "^0.2.1",
Expand Down
8 changes: 8 additions & 0 deletions packages/lib-js-core/src/query-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ export default class QueryBuilder {
return `https://${host}/${apiVersion}`
}

_getSyncanoRegistryURL () {
const {host} = this.instance
const endpointHost = host === 'api.syncano.io' ? 'syncano.space' : 'syncano.link'
const registryInstance = process.env.SYNCANO_SOCKET_REGISTRY_INSTANCE || 'socket-registry'
this.registryHost = `${registryInstance}.${endpointHost}`
return `https://${this.registryHost}`
}

_getInstanceURL (instanceName) {
return `${this._getSyncanoURL()}/instances/${instanceName}`
}
Expand Down
99 changes: 99 additions & 0 deletions packages/lib-js-core/src/registry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import fs from 'fs'
import https from 'https'
import FormData from 'form-data'
import logger from 'debug'
import QueryBuilder from './query-builder'

const debug = logger('core:registry')

/**
* Connection with Syncano Registry.
* @property {Function}
* @example {@lang javascript}
* const socketList = await registry.searchSocketsByAll('facebook')
*/
export default class Socket extends QueryBuilder {
url (registryEndpoint) {
return `${this._getSyncanoRegistryURL()}/${registryEndpoint}/`
}

async searchSocketsByAll (keyword) {
debug(`searchSocketsByAll: ${keyword}`)
const headers = {
'X-Syncano-Account-Key': this.instance.accountKey
}
const options = {
method: 'POST',
body: JSON.stringify({ keyword })
}

return this.nonInstanceFetch(this.url('registry/search'), options, headers)
}

async searchSocketByName (name, version) {
debug(`searchSocketByName: ${name} (${version})`)

const headers = {
'X-Syncano-Account-Key': this.instance.accountKey
}
const options = {
method: 'POST',
body: JSON.stringify({
name,
version
})
}

return this.nonInstanceFetch(this.url('registry/get'), options, headers)
}

async publishSocket (socketName, version) {
debug('publishSocket', socketName)
const headers = {
'X-Syncano-Account-Key': this.instance.accountKey
}
const options = {
method: 'POST',
body: JSON.stringify({
name: socketName,
version
})
}
return this.nonInstanceFetch(this.url('registry/publish'), options, headers)
}

async getSocket (url, fileDescriptor) {
debug('getSocket', url)
return new Promise((resolve, reject) => {
https.get(url, (response) => {
response.pipe(fileDescriptor)
fileDescriptor.on('finish', () => {
debug('Socket zip downloaded')
fileDescriptor.close(resolve)
})
})
})
}

async submitSocket (socketSpec, socketConfig, socketZipPath) {
debug('submitSocket', socketZipPath)

const form = new FormData()
form.append('file', fs.createReadStream(socketZipPath))
form.append('name', socketSpec.name)
form.append('description', socketSpec.description)
form.append('version', socketSpec.version)
form.append('keywords', JSON.stringify(socketSpec.keywords || []))
form.append('config', JSON.stringify(socketConfig))

const headers = form.getHeaders()
headers['X-Syncano-Account-Key'] = this.instance.accountKey

const options = {
method: 'POST',
body: form
}

return this.nonInstanceFetch(this.url('registry/add'), options, headers)
}
}
2 changes: 2 additions & 0 deletions packages/lib-js-core/src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Logger from './logger'
import Channel from './channel'
import Class from './class'
import Settings from './settings'
import Registry from './registry'

class Server {
constructor (ctx = {}) {
Expand All @@ -31,6 +32,7 @@ class Server {
this.instance = new Instance(config)
this.logger = Logger(config)
this.users = new Users(config)
this.registry = new Registry(config)
this.data = new Proxy(new Data(settings), {
get (target, className) {
return new Data(getConfig(className))
Expand Down
Loading