solution: introduce labels for upstreams

This commit is contained in:
Igor Artamonov
2019-08-01 23:43:04 -04:00
parent 045c2fb3fa
commit 2c5551d818
13 changed files with 307 additions and 35 deletions

View File

@@ -26,7 +26,6 @@ class UpstreamsConfigReaderSpec extends Specification {
with(act.upstreams.get(0)) {
id == "local"
chain == "ethereum"
provider == "geth"
connection instanceof UpstreamsConfig.EthereumConnection
with((UpstreamsConfig.EthereumConnection)connection) {
rpc != null
@@ -38,7 +37,6 @@ class UpstreamsConfigReaderSpec extends Specification {
with(act.upstreams.get(1)) {
id == "infura"
chain == "ethereum"
provider == "infura"
connection instanceof UpstreamsConfig.EthereumConnection
with((UpstreamsConfig.EthereumConnection)connection) {
rpc.url == new URI("https://mainnet.infura.io/v3/fa28c968191849c1aff541ad1d8511f2")
@@ -63,7 +61,6 @@ class UpstreamsConfigReaderSpec extends Specification {
act.upstreams.size() == 1
with(act.upstreams.get(0)) {
id == "remote"
provider == "dshackle"
connection instanceof UpstreamsConfig.GrpcConnection
with((UpstreamsConfig.GrpcConnection)connection) {
host == "10.2.0.15"
@@ -76,4 +73,24 @@ class UpstreamsConfigReaderSpec extends Specification {
}
}
}
def "Parse config with labels"() {
setup:
def config = this.class.getClassLoader().getResourceAsStream("upstreams-labels.yaml")
when:
def act = reader.read(config)
then:
act != null
act.upstreams.size() == 2
with(act.upstreams.get(0)) {
connection instanceof UpstreamsConfig.GrpcConnection
labels.isEmpty()
}
with(act.upstreams.get(1)) {
!labels.isEmpty()
labels.size() == 2
labels["fullnode"] == "true"
labels["api"] == "geth"
}
}
}

View File

@@ -0,0 +1,119 @@
package io.emeraldpay.dshackle.upstream
import io.emeraldpay.dshackle.config.UpstreamsConfig
import org.codehaus.groovy.runtime.DefaultGroovyMethods
import spock.lang.Specification
class NodeDetailsListSpec extends Specification {
def "Adds new node"() {
setup:
def list = new NodeDetailsList()
when:
list.add(new NodeDetailsList.NodeDetails(1, asLabels([foo: "bar"])))
then:
list.nodes.size() == 1
with(list.nodes.get(0)) {
quorum == 1
DefaultGroovyMethods.equals(labels, [foo: "bar"])
}
when:
list.add(new NodeDetailsList.NodeDetails(2, asLabels([foo: "not-bar"])))
then:
list.nodes.size() == 2
with(list.nodes.get(0)) {
quorum == 1
DefaultGroovyMethods.equals(labels, [foo: "bar"])
}
with(list.nodes.get(1)) {
quorum == 2
DefaultGroovyMethods.equals(labels, [foo: "not-bar"])
}
when:
list.add(new NodeDetailsList.NodeDetails(1, asLabels([foo: "bar", baz: "baz"])))
then:
list.nodes.size() == 3
with(list.nodes.get(0)) {
quorum == 1
DefaultGroovyMethods.equals(labels, [foo: "bar"])
}
with(list.nodes.get(1)) {
quorum == 2
DefaultGroovyMethods.equals(labels, [foo: "not-bar"])
}
with(list.nodes.get(2)) {
quorum == 1
DefaultGroovyMethods.equals(labels, [foo: "bar", baz: "baz"])
}
}
def "Updates existing node"() {
setup:
def list = new NodeDetailsList()
list.add(new NodeDetailsList.NodeDetails(1, asLabels([foo: "bar"])))
list.add(new NodeDetailsList.NodeDetails(1, asLabels([baz: "true"])))
when:
list.add(new NodeDetailsList.NodeDetails(2, asLabels([baz: "true"])))
then:
list.nodes.size() == 2
with(list.nodes.get(0)) {
quorum == 1
DefaultGroovyMethods.equals(labels, [foo: "bar"])
}
with(list.nodes.get(1)) {
quorum == 3
DefaultGroovyMethods.equals(labels, [baz: "true"])
}
}
def "Applies all from another list"() {
setup:
def list1 = new NodeDetailsList()
list1.add(new NodeDetailsList.NodeDetails(1, asLabels([foo: "bar"])))
list1.add(new NodeDetailsList.NodeDetails(2, asLabels([baz: "true"])))
list1.add(new NodeDetailsList.NodeDetails(3, asLabels([baz: "true", bar: "bar"])))
def list2 = new NodeDetailsList()
list1.add(new NodeDetailsList.NodeDetails(4, asLabels([foo: "bar"])))
list1.add(new NodeDetailsList.NodeDetails(5, asLabels([baz: "true", bar: "bar"])))
list1.add(new NodeDetailsList.NodeDetails(6, asLabels([bar: "bar"])))
def list = new NodeDetailsList()
when:
list.add(list1)
list.add(list2)
def nodes = list.nodes.toSorted { it.quorum }
then:
list.nodes.size() == 4
with(nodes.get(0)) {
quorum == 2
DefaultGroovyMethods.equals(labels, [baz: "true"])
}
with(nodes.get(1)) {
quorum == 1 + 4
DefaultGroovyMethods.equals(labels, [foo: "bar"])
}
with(nodes.get(2)) {
quorum == 6
DefaultGroovyMethods.equals(labels, [bar: "bar"])
}
with(nodes.get(3)) {
quorum == 3 + 5
DefaultGroovyMethods.equals(labels, [baz: "true", bar: "bar"])
}
}
// --------
UpstreamsConfig.Labels asLabels(Map<String, String> values) {
UpstreamsConfig.Labels result = new UpstreamsConfig.Labels()
values.entrySet().forEach {
result.put(it.key, it.value)
}
return result
}
}

View File

@@ -10,7 +10,6 @@ defaultOptions:
upstreams:
- id: local
chain: ethereum
provider: geth
connection:
ethereum:
rpc:
@@ -20,7 +19,6 @@ upstreams:
origin: "http://localhost"
- id: infura
chain: ethereum
provider: infura
connection:
ethereum:
rpc:

View File

@@ -9,7 +9,6 @@ defaultOptions:
upstreams:
- id: remote
provider: dshackle
connection:
grpc:
host: "10.2.0.15"

View File

@@ -0,0 +1,31 @@
version: v1
defaultOptions:
- chains:
- ethereum
options:
disable-syncing: true
min-peers: 3
upstreams:
- id: remote
connection:
grpc:
host: "10.2.0.15"
auth:
type: tls
ca: /etc/ca.myservice.com.crt
certificate: /etc/client1.myservice.com.crt
key: /etc/client1.myservice.com.key
- id: local
chain: ethereum
labels:
api: geth
fullnode: true
connection:
ethereum:
rpc:
url: "http://localhost:8545"
ws:
url: "ws://localhost:8546"
origin: "http://localhost"