Support for publish_address as hostname/ip:port (#804)
This commit is contained in:
committed by
GitHub
parent
5794ad54e4
commit
5af9ec1040
2
lib/ConnectionPool.d.ts
vendored
2
lib/ConnectionPool.d.ts
vendored
@ -127,7 +127,7 @@ export default class ConnectionPool {
|
||||
* @param {object} nodes
|
||||
* @returns {array} hosts
|
||||
*/
|
||||
nodesToHost(nodes: any): any[];
|
||||
nodesToHost(nodes: any, protocol: string): any[];
|
||||
/**
|
||||
* Transforms an url string to a host object
|
||||
*
|
||||
|
||||
@ -332,18 +332,33 @@ class ConnectionPool {
|
||||
* @param {object} nodes
|
||||
* @returns {array} hosts
|
||||
*/
|
||||
nodesToHost (nodes) {
|
||||
nodesToHost (nodes, protocol) {
|
||||
const ids = Object.keys(nodes)
|
||||
const hosts = []
|
||||
|
||||
for (var i = 0, len = ids.length; i < len; i++) {
|
||||
const node = nodes[ids[i]]
|
||||
// If there is no protocol in
|
||||
// the `publish_address` new URL wil throw
|
||||
// the `publish_address` new URL will throw
|
||||
// the publish_address can have two forms:
|
||||
// - ip:port
|
||||
// - hostname/ip:port
|
||||
// if we encounter the second case, we should
|
||||
// use the hostname instead of the ip
|
||||
var address = node.http.publish_address
|
||||
const hostAndIpRegex = /^[a-z0-9_.-]*\/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/gi
|
||||
const match = address.match(hostAndIpRegex)
|
||||
if (match !== null) {
|
||||
const ipRegex = /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/
|
||||
const ip = address.match(ipRegex)[0]
|
||||
// extract the hostname, the -1 at the end removes the final /
|
||||
const hostname = address.slice(0, address.indexOf(ip) - 1)
|
||||
const port = address.split(':')[1]
|
||||
address = `${hostname}:${port}`
|
||||
}
|
||||
address = address.slice(0, 4) === 'http'
|
||||
? address
|
||||
: 'http://' + address
|
||||
: `${protocol}//${address}`
|
||||
const roles = node.roles.reduce((acc, role) => {
|
||||
acc[role] = true
|
||||
return acc
|
||||
|
||||
@ -353,7 +353,8 @@ class Transport {
|
||||
}
|
||||
|
||||
debug('Sniffing ended successfully', result.body)
|
||||
const hosts = this.connectionPool.nodesToHost(result.body.nodes)
|
||||
const protocol = result.meta.connection.url.protocol || 'http:'
|
||||
const hosts = this.connectionPool.nodesToHost(result.body.nodes, protocol)
|
||||
this.connectionPool.update(hosts)
|
||||
|
||||
result.meta.sniff = { hosts, reason }
|
||||
|
||||
@ -93,6 +93,39 @@ test('Should update the connection pool', t => {
|
||||
})
|
||||
})
|
||||
|
||||
test('Should handle hostnames in publish_address', t => {
|
||||
t.plan(10)
|
||||
|
||||
buildCluster({ hostPublishAddress: true }, ({ nodes, shutdown }) => {
|
||||
const client = new Client({
|
||||
node: nodes[Object.keys(nodes)[0]].url
|
||||
})
|
||||
t.strictEqual(client.connectionPool.connections.size, 1)
|
||||
|
||||
client.on(events.SNIFF, (err, request) => {
|
||||
t.error(err)
|
||||
t.strictEqual(
|
||||
request.meta.sniff.reason,
|
||||
Transport.sniffReasons.DEFAULT
|
||||
)
|
||||
})
|
||||
|
||||
// run the sniffer
|
||||
client.transport.sniff((err, hosts) => {
|
||||
t.error(err)
|
||||
t.strictEqual(hosts.length, 4)
|
||||
|
||||
for (var i = 0; i < hosts.length; i++) {
|
||||
// the first node will be an update of the existing one
|
||||
t.strictEqual(hosts[i].url.hostname, 'localhost')
|
||||
}
|
||||
|
||||
t.strictEqual(client.connectionPool.connections.size, 4)
|
||||
})
|
||||
t.teardown(shutdown)
|
||||
})
|
||||
})
|
||||
|
||||
test('Sniff interval', t => {
|
||||
t.plan(10)
|
||||
|
||||
|
||||
@ -282,41 +282,112 @@ test('API', t => {
|
||||
})
|
||||
|
||||
t.test('nodesToHost', t => {
|
||||
const pool = new ConnectionPool({ Connection })
|
||||
const nodes = {
|
||||
a1: {
|
||||
http: {
|
||||
publish_address: '127.0.0.1:9200'
|
||||
t.test('publish_address as ip address', t => {
|
||||
const pool = new ConnectionPool({ Connection })
|
||||
const nodes = {
|
||||
a1: {
|
||||
http: {
|
||||
publish_address: '127.0.0.1:9200'
|
||||
},
|
||||
roles: ['master', 'data', 'ingest']
|
||||
},
|
||||
roles: ['master', 'data', 'ingest']
|
||||
},
|
||||
a2: {
|
||||
http: {
|
||||
publish_address: '127.0.0.1:9202'
|
||||
},
|
||||
roles: ['master', 'data', 'ingest']
|
||||
a2: {
|
||||
http: {
|
||||
publish_address: '127.0.0.1:9201'
|
||||
},
|
||||
roles: ['master', 'data', 'ingest']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t.deepEqual(pool.nodesToHost(nodes), [{
|
||||
url: new URL('http://127.0.0.1:9200'),
|
||||
id: 'a1',
|
||||
roles: {
|
||||
master: true,
|
||||
data: true,
|
||||
ingest: true,
|
||||
ml: false
|
||||
t.deepEqual(pool.nodesToHost(nodes, 'http:'), [{
|
||||
url: new URL('http://127.0.0.1:9200'),
|
||||
id: 'a1',
|
||||
roles: {
|
||||
master: true,
|
||||
data: true,
|
||||
ingest: true,
|
||||
ml: false
|
||||
}
|
||||
}, {
|
||||
url: new URL('http://127.0.0.1:9201'),
|
||||
id: 'a2',
|
||||
roles: {
|
||||
master: true,
|
||||
data: true,
|
||||
ingest: true,
|
||||
ml: false
|
||||
}
|
||||
}])
|
||||
|
||||
t.strictEqual(pool.nodesToHost(nodes, 'http:')[0].url.host, '127.0.0.1:9200')
|
||||
t.strictEqual(pool.nodesToHost(nodes, 'http:')[1].url.host, '127.0.0.1:9201')
|
||||
t.end()
|
||||
})
|
||||
|
||||
t.test('publish_address as host/ip', t => {
|
||||
const pool = new ConnectionPool({ Connection })
|
||||
const nodes = {
|
||||
a1: {
|
||||
http: {
|
||||
publish_address: 'example.com/127.0.0.1:9200'
|
||||
},
|
||||
roles: ['master', 'data', 'ingest']
|
||||
},
|
||||
a2: {
|
||||
http: {
|
||||
publish_address: 'example.com/127.0.0.1:9201'
|
||||
},
|
||||
roles: ['master', 'data', 'ingest']
|
||||
}
|
||||
}
|
||||
}, {
|
||||
url: new URL('http://127.0.0.1:9201'),
|
||||
id: 'a2',
|
||||
roles: {
|
||||
master: true,
|
||||
data: true,
|
||||
ingest: true,
|
||||
ml: false
|
||||
|
||||
t.deepEqual(pool.nodesToHost(nodes, 'http:'), [{
|
||||
url: new URL('http://example.com:9200'),
|
||||
id: 'a1',
|
||||
roles: {
|
||||
master: true,
|
||||
data: true,
|
||||
ingest: true,
|
||||
ml: false
|
||||
}
|
||||
}, {
|
||||
url: new URL('http://example.com:9201'),
|
||||
id: 'a2',
|
||||
roles: {
|
||||
master: true,
|
||||
data: true,
|
||||
ingest: true,
|
||||
ml: false
|
||||
}
|
||||
}])
|
||||
|
||||
t.strictEqual(pool.nodesToHost(nodes, 'http:')[0].url.host, 'example.com:9200')
|
||||
t.strictEqual(pool.nodesToHost(nodes, 'http:')[1].url.host, 'example.com:9201')
|
||||
t.end()
|
||||
})
|
||||
|
||||
t.test('Should use the configure protocol', t => {
|
||||
const pool = new ConnectionPool({ Connection })
|
||||
const nodes = {
|
||||
a1: {
|
||||
http: {
|
||||
publish_address: 'example.com/127.0.0.1:9200'
|
||||
},
|
||||
roles: ['master', 'data', 'ingest']
|
||||
},
|
||||
a2: {
|
||||
http: {
|
||||
publish_address: 'example.com/127.0.0.1:9201'
|
||||
},
|
||||
roles: ['master', 'data', 'ingest']
|
||||
}
|
||||
}
|
||||
}])
|
||||
|
||||
t.strictEqual(pool.nodesToHost(nodes, 'https:')[0].url.protocol, 'https:')
|
||||
t.strictEqual(pool.nodesToHost(nodes, 'http:')[1].url.protocol, 'http:')
|
||||
t.end()
|
||||
})
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
|
||||
@ -53,12 +53,14 @@ function buildCluster (options, callback) {
|
||||
|
||||
buildServer(options.handler || handler, ({ port }, server) => {
|
||||
nodes[opts.id] = {
|
||||
url: `http://localhost:${port}`,
|
||||
url: `http://127.0.0.1:${port}`,
|
||||
server
|
||||
}
|
||||
sniffResult.nodes[opts.id] = {
|
||||
http: {
|
||||
publish_address: `http://localhost:${port}`
|
||||
publish_address: options.hostPublishAddress
|
||||
? `localhost/127.0.0.1:${port}`
|
||||
: `127.0.0.1:${port}`
|
||||
},
|
||||
roles: ['master', 'data', 'ingest']
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user