diff --git a/CHANGES.md b/CHANGES.md index 13e8235416..b9b6abcf49 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -72,6 +72,7 @@ Release Notes. * Support session expired threshold configurable. * Fix InfluxDB storage-plugin Metrics#multiGet issue. * Replace zuul proxy with spring cloud gateway 2.x. in webapp module. +* Upgrade etcd cluster coordinator and dynamic configuration to v3.x. #### UI diff --git a/dist-material/release-docs/LICENSE b/dist-material/release-docs/LICENSE index 98a9dd8569..ecb5a6f463 100755 --- a/dist-material/release-docs/LICENSE +++ b/dist-material/release-docs/LICENSE @@ -320,11 +320,9 @@ The text of each license is the standard Apache 2.0 license. proto files from lyft/protoc-gen-validate: https://github.com/lyft/protoc-gen-validate Apache 2.0 proto files from gogo/googleapis: https://github.com/gogo/googleapis Apache 2.0 flatbuffers files from istio/proxy: https://github.com/istio/proxy Apache 2.0 - json-flatter 0.6.0: https://github.com/wnameless/json-flattener Apache 2.0 Apache: commons-text 1.4: https://github.com/apache/commons-text Apache 2.0 sundrio 0.9.2: https://github.com/sundrio/sundrio Apache 2.0 Ctripcorp: apollo 1.8.0: https://github.com/ctripcorp/apollo Apache 2.0 - etcd4j 2.18.0: https://github.com/jurmous/etcd4j Apache 2.0 javaassist 3.25.0-GA: https://github.com/jboss-javassist/javassist Apache 2.0 jackson-module-afterburner 2.12.2: https://github.com/FasterXML/jackson-modules-base, Apache 2.0 perfmark-api 0.19.0: https://github.com/perfmark/perfmark, Apache 2.0 @@ -343,6 +341,8 @@ The text of each license is the standard Apache 2.0 license. okio 1.17.2: https://github.com/square/okio Apache 2.0 caffeine 2.6.2: https://github.com/ben-manes/caffeine Apache 2.0 simpleclient_httpserver from prometheus https://github.com/prometheus/client_java Apache 2.0 + jetcd 0.5.3, https://github.com/etcd-io/jetcd, Apache 2.0 + failasfe 2.3.4, https://github.com/jhalterman/failsafe, Apache 2.0 ======================================================================== MIT licenses diff --git a/dist-material/release-docs/NOTICE b/dist-material/release-docs/NOTICE index 5b363ade12..63036b2ed6 100755 --- a/dist-material/release-docs/NOTICE +++ b/dist-material/release-docs/NOTICE @@ -896,3 +896,17 @@ This distribution has a binary dependency on jersey, which is available under th License. The source code of jersey can be found at https://github.com/jersey/jersey/. ======================================================================== + +------ + +=========================================================================== +jetcd Notice +=========================================================================== + +CoreOS Project +Copyright 2018 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). + +=========================================================================== diff --git a/docs/en/setup/backend/backend-cluster.md b/docs/en/setup/backend/backend-cluster.md index 80247f0196..dcd025a0f9 100644 --- a/docs/en/setup/backend/backend-cluster.md +++ b/docs/en/setup/backend/backend-cluster.md @@ -89,12 +89,20 @@ The following settings are provided to set the host and port manually, based on ## Etcd -Set the **cluster/selector** to **etcd** in the yml to enable it. +Set the **cluster/selector** to **etcd** in the yml to enable it. The Etcd client has upgraded to v3 protocol and changed to the CoreOS official library. **Since 8.7.0, only the v3 protocol is supported for Etcd.** ```yaml cluster: selector: ${SW_CLUSTER:etcd} # other configurations + etcd: + # etcd cluster nodes, example: 10.0.0.1:2379,10.0.0.2:2379,10.0.0.3:2379 + endpoints: ${SW_CLUSTER_ETCD_ENDPOINTS:localhost:2379} + namespace: ${SW_CLUSTER_ETCD_NAMESPACE:/skywalking} + serviceName: ${SW_SCLUSTER_ETCD_ERVICE_NAME:"SkyWalking_OAP_Cluster"} + authentication: ${SW_CLUSTER_ETCD_AUTHENTICATION:false} + user: ${SW_SCLUSTER_ETCD_USER:} + password: ${SW_SCLUSTER_ETCD_PASSWORD:} ``` Same as the Zookeeper coordinator, diff --git a/docs/en/setup/backend/configuration-vocabulary.md b/docs/en/setup/backend/configuration-vocabulary.md index 6969c80355..843f95eb5d 100644 --- a/docs/en/setup/backend/configuration-vocabulary.md +++ b/docs/en/setup/backend/configuration-vocabulary.md @@ -64,11 +64,12 @@ core|default|role|Option values, `Mixed/Receiver/Aggregator`. **Receiver** mode | - | - | aclToken| ALC Token of Consul. Empty string means `without ALC token`.| SW_CLUSTER_CONSUL_ACLTOKEN | - | | - | - | internalComHost| The hostname registered in the Consul for the internal communication of OAP cluster.| - | -| | - | - | internalComPort| The port registered in the Consul for the internal communication of OAP cluster.| - | -1| -| - | etcd| serviceName| Service name used for SkyWalking cluster. |SW_SERVICE_NAME|SkyWalking_OAP_Cluster| -| - | - | hostPort| hosts and ports used of etcd cluster.| SW_CLUSTER_ETCD_HOST_PORT|localhost:2379| -| - | - | isSSL| Open SSL for the connection between SkyWalking and etcd cluster.| - | - | -| - | - | internalComHost| The hostname registered in the etcd for the internal communication of OAP cluster.| - | -| -| - | - | internalComPort| The port registered in the etcd for the internal communication of OAP cluster.| - | -1| +| - | etcd| serviceName| Service name used for SkyWalking cluster. |SW_CLUSTER_ETCD_SERVICE_NAME|SkyWalking_OAP_Cluster| +| - | - | endpoints| hosts and ports used of etcd cluster.| SW_CLUSTER_ETCD_ENDPOINTS|localhost:2379| +| - | - | namespace | Namespace used for SkyWalking cluster. |SW_CLUSTER_ETCD_NAMESPACE | /skywalking | +| - | - | authentication | Whether has authentication. | SW_CLUSTER_ETCD_AUTHENTICATION | false | +| - | - | user | Etcd auth username | SW_CLUSTER_ETCD_USER | | +| - | - | password | Etcd auth password | SW_CLUSTER_ETCD_PASSWORD | | | - | Nacos| serviceName| Service name used for SkyWalking cluster. |SW_SERVICE_NAME|SkyWalking_OAP_Cluster| | - | - | hostPort| hosts and ports used of Nacos cluster.| SW_CLUSTER_NACOS_HOST_PORT|localhost:8848| | - | - | namespace| Namespace used by SkyWalking node coordination.| SW_CLUSTER_NACOS_NAMESPACE|public| @@ -264,9 +265,11 @@ core|default|role|Option values, `Mixed/Receiver/Aggregator`. **Receiver** mode | - | - | baseSleepTimeMs|The period of Zookeeper client between two retries. Unit is ms.|SW_CONFIG_ZK_BASE_SLEEP_TIME_MS|1000| | - | - | maxRetries| The max retry time of re-trying.|SW_CONFIG_ZK_MAX_RETRIES|3| | - | - | period | The period of data sync. Unit is second. | SW_CONFIG_ZK_PERIOD | 60 | -| - | etcd| clusterName| Service name used for SkyWalking cluster. |SW_CONFIG_ETCD_CLUSTER_NAME|default| -| - | - | serverAddr| hosts and ports used of etcd cluster.| SW_CONFIG_ETCD_SERVER_ADDR|localhost:2379| -| - | - | group |Additional prefix of the configuration key| SW_CONFIG_ETCD_GROUP | skywalking| +| - | etcd| endpoints | hosts and ports used of etcd cluster(If there are multiple, separate them with commas). | SW_CONFIG_ETCD_ENDPOINTS | localhost:2379 | +| - | - | namespace | Namespace used for SkyWalking cluster. |SW_CONFIG_ETCD_NAMESPACE | /skywalking | +| - | - | authentication | Whether has authentication. | SW_CONFIG_ETCD_AUTHENTICATION | false | +| - | - | user | Etcd auth username | SW_CONFIG_ETCD_USER | | +| - | - | password | Etcd auth password | SW_CONFIG_ETCD_PASSWORD | | | - | - | period | The period of data sync. Unit is second. | SW_CONFIG_ZK_PERIOD | 60 | - | consul | hostPort| hosts and ports used of Consul cluster.| SW_CONFIG_CONSUL_HOST_AND_PORTS|localhost:8500| | - | - | aclToken| ALC Token of Consul. Empty string means `without ALC token`.| SW_CONFIG_CONSUL_ACL_TOKEN | - | diff --git a/docs/en/setup/backend/dynamic-config.md b/docs/en/setup/backend/dynamic-config.md index 5f942009cd..44b7f8650b 100755 --- a/docs/en/setup/backend/dynamic-config.md +++ b/docs/en/setup/backend/dynamic-config.md @@ -70,11 +70,15 @@ configuration: selector: ${SW_CONFIGURATION:etcd} etcd: period: ${SW_CONFIG_ETCD_PERIOD:60} # Unit seconds, sync period. Default fetch every 60 seconds. - group: ${SW_CONFIG_ETCD_GROUP:skywalking} - serverAddr: ${SW_CONFIG_ETCD_SERVER_ADDR:localhost:2379} - clusterName: ${SW_CONFIG_ETCD_CLUSTER_NAME:default} + endpoints: ${SW_CONFIG_ETCD_ENDPOINTS:localhost:2379} + namespace: ${SW_CONFIG_ETCD_NAMESPACE:/skywalking} + authentication: ${SW_CONFIG_ETCD_AUTHENTICATION:false} + user: ${SW_CONFIG_ETCD_USER:} + password: ${SW_CONFIG_ETCD_password:} ``` +**NOTICE**, only the v3 protocol is supported since 8.7.0. + ## Dynamic Configuration Consul Implementation [Consul](https://github.com/rickfast/consul-client) is also supported as DCC(Dynamic Configuration Center), to use it, please configure as follows: diff --git a/oap-server-bom/pom.xml b/oap-server-bom/pom.xml index 69812c0a73..6fad449b8e 100644 --- a/oap-server-bom/pom.xml +++ b/oap-server-bom/pom.xml @@ -73,10 +73,19 @@ 1.9.4 1.12.0 42.2.18 + 0.5.3 + 1.15.3 + + io.netty + netty-bom + ${netty.version} + import + pom + org.slf4j slf4j-api @@ -200,6 +209,16 @@ io.grpc grpc-netty ${grpc.version} + + + io.netty + netty-codec-http2 + + + io.netty + netty-handler-proxy + + io.grpc @@ -252,6 +271,11 @@ + + io.grpc + grpc-grpclb + ${grpc.version} + org.eclipse.jetty jetty-server @@ -329,65 +353,37 @@ nacos-client ${nacos.version} + - org.mousio - etcd4j + io.etcd + jetcd-core + ${jetcd.version} - netty-codec-dns - io.netty + io.grpc + grpc-core - - netty-codec-dns - io.netty + io.grpc + grpc-netty - - netty-codec-http - io.netty + io.grpc + grpc-protobuf - - netty-handler - io.netty + io.grpc + grpc-stub - - netty-resolver-dns - io.netty + io.grpc + grpc-grpclb - - com.fasterxml.jackson.module - jackson-module-afterburner + org.slf4j + slf4j-api - ${etcd4j.version} - - - - io.netty - netty-handler - ${netty.version} - - - - io.netty - netty-resolver-dns - ${netty.version} - - - - io.netty - netty-codec-dns - ${netty.version} - - - - io.netty - netty-codec-http - ${netty.version} @@ -496,6 +492,13 @@ postgresql ${postgresql.version} + + + org.testcontainers + testcontainers + ${testcontainers.version} + test + diff --git a/oap-server/pom.xml b/oap-server/pom.xml index 00d2f75eb9..6fa7990e65 100755 --- a/oap-server/pom.xml +++ b/oap-server/pom.xml @@ -54,7 +54,6 @@ UTF-8 0.30.0 - v3.2.3 3.5 2.4.1 2.4.6.RELEASE diff --git a/oap-server/server-bootstrap/src/main/resources/application.yml b/oap-server/server-bootstrap/src/main/resources/application.yml index d27121b942..7866d4c504 100755 --- a/oap-server/server-bootstrap/src/main/resources/application.yml +++ b/oap-server/server-bootstrap/src/main/resources/application.yml @@ -38,9 +38,13 @@ cluster: hostPort: ${SW_CLUSTER_CONSUL_HOST_PORT:localhost:8500} aclToken: ${SW_CLUSTER_CONSUL_ACLTOKEN:""} etcd: - serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"} # etcd cluster nodes, example: 10.0.0.1:2379,10.0.0.2:2379,10.0.0.3:2379 - hostPort: ${SW_CLUSTER_ETCD_HOST_PORT:localhost:2379} + endpoints: ${SW_CLUSTER_ETCD_ENDPOINTS:localhost:2379} + namespace: ${SW_CLUSTER_ETCD_NAMESPACE:/skywalking} + serviceName: ${SW_SCLUSTER_ETCD_ERVICE_NAME:"SkyWalking_OAP_Cluster"} + authentication: ${SW_CLUSTER_ETCD_AUTHENTICATION:false} + user: ${SW_SCLUSTER_ETCD_USER:} + password: ${SW_SCLUSTER_ETCD_PASSWORD:} nacos: serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"} hostPort: ${SW_CLUSTER_NACOS_HOST_PORT:localhost:8848} @@ -448,9 +452,11 @@ configuration: maxRetries: ${SW_CONFIG_ZK_MAX_RETRIES:3} # max number of times to retry etcd: period: ${SW_CONFIG_ETCD_PERIOD:60} # Unit seconds, sync period. Default fetch every 60 seconds. - group: ${SW_CONFIG_ETCD_GROUP:skywalking} - serverAddr: ${SW_CONFIG_ETCD_SERVER_ADDR:localhost:2379} - clusterName: ${SW_CONFIG_ETCD_CLUSTER_NAME:default} + endpoints: ${SW_CONFIG_ETCD_ENDPOINTS:localhost:2379} + namespace: ${SW_CONFIG_ETCD_NAMESPACE:/skywalking} + authentication: ${SW_CONFIG_ETCD_AUTHENTICATION:false} + user: ${SW_CONFIG_ETCD_USER:} + password: ${SW_CONFIG_ETCD_password:} consul: # Consul host and ports, separated by comma, e.g. 1.2.3.4:8500,2.3.4.5:8500 hostAndPorts: ${SW_CONFIG_CONSUL_HOST_AND_PORTS:1.2.3.4:8500} diff --git a/oap-server/server-cluster-plugin/cluster-etcd-plugin/pom.xml b/oap-server/server-cluster-plugin/cluster-etcd-plugin/pom.xml index 47d46c758c..311ff9ab11 100644 --- a/oap-server/server-cluster-plugin/cluster-etcd-plugin/pom.xml +++ b/oap-server/server-cluster-plugin/cluster-etcd-plugin/pom.xml @@ -37,35 +37,54 @@ - io.netty - netty-codec-dns + io.etcd + jetcd-core + + + + io.grpc + grpc-core + + + + io.grpc + grpc-netty io.netty - netty-codec-http + netty-codec-http2 io.netty - netty-handler + netty-handler-proxy - io.netty - netty-resolver-dns + io.grpc + grpc-protobuf - org.mousio - etcd4j + io.grpc + grpc-stub - com.fasterxml.jackson.module - jackson-module-afterburner + io.grpc + grpc-grpclb + + org.yaml + snakeyaml + + + + org.testcontainers + testcontainers + @@ -73,70 +92,9 @@ CI-with-IT - - io.fabric8 - docker-maven-plugin - - all - default - true - IfNotPresent - - - - start - pre-integration-test - - start - - - - - quayio/coreos-etcd:${etcd.version} - etcd-client-integration-test - - - +etcd.host:etcd.port:2379 - - - - - - - - /usr/local/bin/etcd - --advertise-client-urls=http://0.0.0.0:2379 - --listen-client-urls=http://0.0.0.0:2379 - - - - - - - - - remove-it-etcd - post-integration-test - - stop - - - - - org.apache.maven.plugins maven-failsafe-plugin - - - - ${etcd.host} - - - ${etcd.port} - - - diff --git a/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ClusterModuleEtcdConfig.java b/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ClusterModuleEtcdConfig.java index bba372782d..ff98a7cda5 100644 --- a/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ClusterModuleEtcdConfig.java +++ b/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ClusterModuleEtcdConfig.java @@ -18,25 +18,38 @@ package org.apache.skywalking.oap.server.cluster.plugin.etcd; -import lombok.Getter; -import lombok.Setter; +import com.google.common.base.Strings; +import java.util.Arrays; +import lombok.Data; import org.apache.skywalking.oap.server.library.module.ModuleConfig; +@Data public class ClusterModuleEtcdConfig extends ModuleConfig { - - @Setter - @Getter private String serviceName; - @Setter - @Getter - private String hostPort; - @Setter - @Getter - private boolean isSSL; - @Setter - @Getter + private String endpoints; + private String namespace; + + private String authority; + + private boolean authentication; + private String user; + private String password; + private String internalComHost; - @Setter - @Getter private int internalComPort = -1; + + public String getNamespace() { + if (Strings.isNullOrEmpty(namespace)) { + return null; + } + if (!namespace.endsWith("/")) { + return namespace + "/"; + } + return namespace; + } + + public String[] getEndpointArray() { + return Arrays.stream(endpoints.split("\\s*,\\s*")).toArray(String[]::new); + + } } diff --git a/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ClusterModuleEtcdProvider.java b/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ClusterModuleEtcdProvider.java index 553471d0f7..0ff9b77014 100644 --- a/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ClusterModuleEtcdProvider.java +++ b/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ClusterModuleEtcdProvider.java @@ -18,9 +18,6 @@ package org.apache.skywalking.oap.server.cluster.plugin.etcd; -import java.net.URI; -import java.util.List; -import mousio.etcd4j.EtcdClient; import org.apache.skywalking.oap.server.core.CoreModule; import org.apache.skywalking.oap.server.core.cluster.ClusterModule; import org.apache.skywalking.oap.server.core.cluster.ClusterNodesQuery; @@ -38,10 +35,7 @@ public class ClusterModuleEtcdProvider extends ModuleProvider { private final ClusterModuleEtcdConfig config; - private EtcdClient client; - public ClusterModuleEtcdProvider() { - super(); this.config = new ClusterModuleEtcdConfig(); } @@ -62,12 +56,13 @@ public class ClusterModuleEtcdProvider extends ModuleProvider { @Override public void prepare() throws ServiceNotProvidedException, ModuleStartException { - List uris = EtcdUtils.parse(config); - //TODO check isSSL - client = new EtcdClient(uris.toArray(new URI[] {})); - EtcdCoordinator coordinator = new EtcdCoordinator(getManager(), config, client); - this.registerServiceImplementation(ClusterRegister.class, coordinator); - this.registerServiceImplementation(ClusterNodesQuery.class, coordinator); + try { + EtcdCoordinator coordinator = new EtcdCoordinator(getManager(), config); + this.registerServiceImplementation(ClusterRegister.class, coordinator); + this.registerServiceImplementation(ClusterNodesQuery.class, coordinator); + } catch (Exception e) { + throw new ModuleStartException("Failed to start ETCD coordinator.", e); + } } @Override diff --git a/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/EtcdCoordinator.java b/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/EtcdCoordinator.java index 8d20d475d6..aceb581b12 100644 --- a/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/EtcdCoordinator.java +++ b/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/EtcdCoordinator.java @@ -20,15 +20,21 @@ package org.apache.skywalking.oap.server.cluster.plugin.etcd; import com.google.common.base.Strings; import com.google.gson.Gson; +import io.etcd.jetcd.ByteSequence; +import io.etcd.jetcd.Client; +import io.etcd.jetcd.ClientBuilder; +import io.etcd.jetcd.KV; +import io.etcd.jetcd.Lease; +import io.etcd.jetcd.kv.GetResponse; +import io.etcd.jetcd.lease.LeaseKeepAliveResponse; +import io.etcd.jetcd.options.GetOption; +import io.etcd.jetcd.options.PutOption; +import io.grpc.stub.StreamObserver; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import mousio.etcd4j.EtcdClient; -import mousio.etcd4j.promises.EtcdResponsePromise; -import mousio.etcd4j.responses.EtcdKeysResponse; +import lombok.extern.slf4j.Slf4j; +import org.apache.skywalking.apm.util.StringUtil; import org.apache.skywalking.oap.server.core.cluster.ClusterHealthStatus; import org.apache.skywalking.oap.server.core.cluster.ClusterNodesQuery; import org.apache.skywalking.oap.server.core.cluster.ClusterRegister; @@ -37,30 +43,48 @@ import org.apache.skywalking.oap.server.core.cluster.RemoteInstance; import org.apache.skywalking.oap.server.core.cluster.ServiceRegisterException; import org.apache.skywalking.oap.server.core.remote.client.Address; import org.apache.skywalking.oap.server.library.module.ModuleDefineHolder; +import org.apache.skywalking.oap.server.library.module.ModuleStartException; import org.apache.skywalking.oap.server.telemetry.TelemetryModule; import org.apache.skywalking.oap.server.telemetry.api.HealthCheckMetrics; import org.apache.skywalking.oap.server.telemetry.api.MetricsCreator; import org.apache.skywalking.oap.server.telemetry.api.MetricsTag; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class EtcdCoordinator implements ClusterRegister, ClusterNodesQuery { - private static final Logger LOGGER = LoggerFactory.getLogger(EtcdCoordinator.class); - private static final Integer KEY_TTL = 45; - + private static final Gson GSON = new Gson().newBuilder().create(); private final ModuleDefineHolder manager; private final ClusterModuleEtcdConfig config; - private final EtcdClient client; - private final String serviceName; - private final ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); private volatile Address selfAddress; private HealthCheckMetrics healthChecker; - public EtcdCoordinator(final ModuleDefineHolder manager, final ClusterModuleEtcdConfig config, final EtcdClient client) { + private final Client client; + private final String serviceName; + private final ByteSequence serviceNameBS; + + public EtcdCoordinator(final ModuleDefineHolder manager, + final ClusterModuleEtcdConfig config) throws ModuleStartException { + if (Strings.isNullOrEmpty(config.getServiceName())) { + throw new ModuleStartException("ServiceName cannot be empty."); + } this.manager = manager; this.config = config; - this.client = client; - this.serviceName = config.getServiceName(); + if (!config.getServiceName().endsWith("/")) { + serviceName = config.getServiceName() + "/"; + } else { + serviceName = config.getServiceName(); + } + this.serviceNameBS = ByteSequence.from(serviceName, Charset.defaultCharset()); + ClientBuilder builder = Client.builder() + .endpoints(config.getEndpointArray()) + .authority(config.getAuthority()); + if (StringUtil.isNotEmpty(config.getNamespace())) { + builder.namespace(ByteSequence.from(config.getNamespace(), Charset.defaultCharset())); + } + if (config.isAuthentication()) { + builder.user(ByteSequence.from(config.getUser(), Charset.defaultCharset())) + .password(ByteSequence.from(config.getPassword(), Charset.defaultCharset())); + } + this.client = builder.build(); } @Override @@ -68,20 +92,25 @@ public class EtcdCoordinator implements ClusterRegister, ClusterNodesQuery { List remoteInstances = new ArrayList<>(); try { initHealthChecker(); - EtcdKeysResponse response = client.get(serviceName + "/").send().get(); - List nodes = response.getNode().getNodes(); - Gson gson = new Gson(); - if (nodes != null) { - nodes.forEach(node -> { - EtcdEndpoint endpoint = gson.fromJson(node.getValue(), EtcdEndpoint.class); - Address address = new Address(endpoint.getHost(), endpoint.getPort(), true); - if (!address.equals(selfAddress)) { - address.setSelf(false); - } - remoteInstances.add(new RemoteInstance(address)); - }); - } + final KV kvClient = client.getKVClient(); + final GetResponse response = kvClient.get( + serviceNameBS, + GetOption.newBuilder().withPrefix(serviceNameBS).build() + ).get(); + + response.getKvs().forEach(kv -> { + EtcdEndpoint endpoint = GSON.fromJson( + kv.getValue().toString(Charset.defaultCharset()), + EtcdEndpoint.class + ); + Address address = new Address(endpoint.getHost(), endpoint.getPort(), false); + if (address.equals(selfAddress)) { + address.setSelf(true); + } + remoteInstances.add(new RemoteInstance(address)); + }); + ClusterHealthStatus healthStatus = OAPNodeChecker.isHealth(remoteInstances); if (healthStatus.isHealth()) { this.healthChecker.health(); @@ -97,54 +126,63 @@ public class EtcdCoordinator implements ClusterRegister, ClusterNodesQuery { @Override public void registerRemote(RemoteInstance remoteInstance) throws ServiceRegisterException { - if (needUsingInternalAddr()) { - remoteInstance = new RemoteInstance(new Address(config.getInternalComHost(), config.getInternalComPort(), true)); + remoteInstance = new RemoteInstance( + new Address(config.getInternalComHost(), config.getInternalComPort(), true)); } this.selfAddress = remoteInstance.getAddress(); - - EtcdEndpoint endpoint = new EtcdEndpoint.Builder().serviceName(serviceName) - .host(selfAddress.getHost()) - .port(selfAddress.getPort()) - .build(); + final EtcdEndpoint endpoint = new EtcdEndpoint.Builder().serviceName(serviceName) + .host(selfAddress.getHost()) + .port(selfAddress.getPort()) + .build(); try { initHealthChecker(); - client.putDir(serviceName).send(); - String key = buildKey(serviceName, selfAddress, remoteInstance); - String json = new Gson().toJson(endpoint); - EtcdResponsePromise promise = client.put(key, json).ttl(KEY_TTL).send(); - //check register. - promise.get(); - renew(client, key, json); + + final Lease leaseClient = client.getLeaseClient(); + final long leaseID = leaseClient.grant(30L).get().getID(); + + ByteSequence instance = ByteSequence.from(GSON.toJson(endpoint), Charset.defaultCharset()); + client.getKVClient() + .put( + buildKey(serviceName, selfAddress, remoteInstance), + instance, + PutOption.newBuilder().withLeaseId(leaseID).build() + ) + .get(); healthChecker.health(); + + client.getLeaseClient().keepAlive(leaseID, new StreamObserver() { + @Override + public void onNext(final LeaseKeepAliveResponse response) { + if (log.isDebugEnabled()) { + log.debug("Refresh lease id = {}, ttl = {}", response.getID(), response.getTTL()); + } + } + + @Override + public void onError(final Throwable throwable) { + log.error("Failed to keep alive in Etcd coordinator", throwable); + healthChecker.unHealth(throwable); + } + + @Override + public void onCompleted() { + + } + }); } catch (Throwable e) { healthChecker.unHealth(e); throw new ServiceRegisterException(e.getMessage()); } - } - private void renew(EtcdClient client, String key, String json) { - service.scheduleAtFixedRate(() -> { - try { - client.refresh(key, KEY_TTL).send().get(); - } catch (Exception e) { - try { - client.put(key, json).ttl(KEY_TTL).send().get(); - } catch (Exception ee) { - LOGGER.error(ee.getMessage(), ee); - } - } - }, 5 * 1000, 30 * 1000, TimeUnit.MILLISECONDS); - } - - private String buildKey(String serviceName, Address address, RemoteInstance instance) { - return new StringBuilder(serviceName).append("/") - .append(address.getHost()) - .append("_") - .append(instance.hashCode()) - .toString(); + private static ByteSequence buildKey(String serviceName, Address address, RemoteInstance instance) { + String key = new StringBuilder(serviceName).append(address.getHost()) + .append("_") + .append(instance.hashCode()) + .toString(); + return ByteSequence.from(key, Charset.defaultCharset()); } private boolean needUsingInternalAddr() { @@ -153,8 +191,11 @@ public class EtcdCoordinator implements ClusterRegister, ClusterNodesQuery { private void initHealthChecker() { if (healthChecker == null) { - MetricsCreator metricCreator = manager.find(TelemetryModule.NAME).provider().getService(MetricsCreator.class); - healthChecker = metricCreator.createHealthCheckerGauge("cluster_etcd", MetricsTag.EMPTY_KEY, MetricsTag.EMPTY_VALUE); + MetricsCreator metricCreator = manager.find(TelemetryModule.NAME) + .provider() + .getService(MetricsCreator.class); + healthChecker = metricCreator.createHealthCheckerGauge( + "cluster_etcd", MetricsTag.EMPTY_KEY, MetricsTag.EMPTY_VALUE); } } } diff --git a/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/EtcdUtils.java b/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/EtcdUtils.java deleted file mode 100644 index ad848e8827..0000000000 --- a/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/EtcdUtils.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.apache.skywalking.oap.server.cluster.plugin.etcd; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; -import org.apache.skywalking.oap.server.library.module.ModuleStartException; -import org.apache.skywalking.oap.server.library.util.Address; -import org.apache.skywalking.oap.server.library.util.ConnectStringParseException; -import org.apache.skywalking.oap.server.library.util.ConnectUtils; - -public class EtcdUtils { - - public EtcdUtils() { - } - - public static List parse(ClusterModuleEtcdConfig config) throws ModuleStartException { - List uris = new ArrayList<>(); - try { - List
addressList = ConnectUtils.parse(config.getHostPort()); - for (Address address : addressList) { - uris.add(URI.create(new StringBuilder("http://").append(address.getHost()) - .append(":") - .append(address.getPort()) - .toString())); - } - } catch (ConnectStringParseException e) { - throw new ModuleStartException(e.getMessage(), e); - } - - return uris; - } -} diff --git a/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/test/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ITClusterEtcdPluginTest.java b/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/test/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ITClusterEtcdPluginTest.java index 0490b62efc..6f1e4e6f92 100644 --- a/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/test/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ITClusterEtcdPluginTest.java +++ b/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/test/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ITClusterEtcdPluginTest.java @@ -18,63 +18,68 @@ package org.apache.skywalking.oap.server.cluster.plugin.etcd; -import java.net.URI; +import io.etcd.jetcd.ByteSequence; +import io.etcd.jetcd.Client; +import io.etcd.jetcd.kv.GetResponse; +import io.etcd.jetcd.options.GetOption; +import java.nio.charset.Charset; +import java.util.Collections; import java.util.List; -import mousio.etcd4j.EtcdClient; -import mousio.etcd4j.responses.EtcdKeysResponse; +import lombok.extern.slf4j.Slf4j; import org.apache.skywalking.oap.server.core.cluster.RemoteInstance; import org.apache.skywalking.oap.server.core.remote.client.Address; import org.apache.skywalking.oap.server.library.module.ModuleDefineHolder; import org.apache.skywalking.oap.server.telemetry.api.HealthCheckMetrics; -import org.junit.After; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; import org.powermock.reflect.Whitebox; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.DockerImageName; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; +@Slf4j public class ITClusterEtcdPluginTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(ITClusterEtcdPluginTest.class); - private ClusterModuleEtcdConfig etcdConfig; - private EtcdClient client; + private Client client; private HealthCheckMetrics healthChecker = mock(HealthCheckMetrics.class); private EtcdCoordinator coordinator; - private Address remoteAddress = new Address("10.0.0.1", 1000, false); - private Address selfRemoteAddress = new Address("10.0.0.2", 1001, true); - - private Address internalAddress = new Address("10.0.0.3", 1002, false); + private final Address remoteAddress = new Address("10.0.0.1", 1000, false); + private final Address selfRemoteAddress = new Address("10.0.0.2", 1001, true); + private final Address internalAddress = new Address("10.0.0.3", 1002, false); private static final String SERVICE_NAME = "my-service"; + @ClassRule + public static final GenericContainer CONTAINER = + new GenericContainer(DockerImageName.parse("bitnami/etcd:3.5.0")) + .waitingFor(Wait.forLogMessage(".*etcd setup finished!.*", 1)) + .withEnv(Collections.singletonMap("ALLOW_NONE_AUTHENTICATION", "yes")); + @Before public void before() throws Exception { - String etcdHost = System.getProperty("etcd.host"); - String port = System.getProperty("etcd.port"); - String baseUrl = "http://" + etcdHost + ":" + port; - LOGGER.info("etcd baseURL: {}", baseUrl); + String baseUrl = "http://127.0.0.1:" + CONTAINER.getMappedPort(2379); etcdConfig = new ClusterModuleEtcdConfig(); - etcdConfig.setServiceName(SERVICE_NAME); - client = new EtcdClient(URI.create(baseUrl)); - doNothing().when(healthChecker).health(); - ModuleDefineHolder manager = mock(ModuleDefineHolder.class); - coordinator = new EtcdCoordinator(manager, etcdConfig, client); - Whitebox.setInternalState(coordinator, "healthChecker", healthChecker); - } + etcdConfig.setEndpoints(baseUrl); + etcdConfig.setNamespace("skywalking/"); - @After - public void after() throws Exception { - client.close(); + etcdConfig.setServiceName(SERVICE_NAME); + doNothing().when(healthChecker).health(); + + ModuleDefineHolder manager = mock(ModuleDefineHolder.class); + coordinator = new EtcdCoordinator(manager, etcdConfig); + + client = Whitebox.getInternalState(coordinator, "client"); + Whitebox.setInternalState(coordinator, "healthChecker", healthChecker); } @Test @@ -128,12 +133,20 @@ public class ITClusterEtcdPluginTest { } private void clear() throws Throwable { - EtcdKeysResponse response = client.get(SERVICE_NAME + "/").send().get(); - List nodes = response.getNode().getNodes(); + ByteSequence prefix = ByteSequence.from(SERVICE_NAME + "/", Charset.defaultCharset()); + GetResponse response = client.getKVClient() + .get( + ByteSequence.EMPTY, + GetOption.newBuilder().withPrefix(prefix).build() + ).get(); - for (EtcdKeysResponse.EtcdNode node : nodes) { - client.delete(node.getKey()).send().get(); - } + response.getKvs().forEach(e -> { + try { + client.getKVClient().delete(e.getKey()).get(); + } catch (Exception exp) { + log.error("", exp); + } + }); } private void verifyRegistration(Address remoteAddress, EtcdEndpoint endpoint) { diff --git a/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/test/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ITClusterModuleEtcdProviderFunctionalTest.java b/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/test/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ITClusterModuleEtcdProviderFunctionalTest.java index c8e95c5d8f..adc841b314 100644 --- a/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/test/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ITClusterModuleEtcdProviderFunctionalTest.java +++ b/oap-server/server-cluster-plugin/cluster-etcd-plugin/src/test/java/org/apache/skywalking/oap/server/cluster/plugin/etcd/ITClusterModuleEtcdProviderFunctionalTest.java @@ -18,9 +18,9 @@ package org.apache.skywalking.oap.server.cluster.plugin.etcd; +import io.etcd.jetcd.Client; import java.util.Collections; import java.util.List; -import mousio.etcd4j.EtcdClient; import org.apache.skywalking.apm.util.StringUtil; import org.apache.skywalking.oap.server.core.cluster.ClusterNodesQuery; import org.apache.skywalking.oap.server.core.cluster.ClusterRegister; @@ -34,9 +34,13 @@ import org.apache.skywalking.oap.server.telemetry.api.MetricsCreator; import org.apache.skywalking.oap.server.telemetry.none.MetricsCreatorNoop; import org.apache.skywalking.oap.server.telemetry.none.NoneTelemetryProvider; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; import org.mockito.Mockito; import org.powermock.reflect.Whitebox; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.DockerImageName; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -45,21 +49,20 @@ import static org.mockito.Mockito.mock; public class ITClusterModuleEtcdProviderFunctionalTest { - private String etcdAddress; - private ModuleManager moduleManager = mock(ModuleManager.class); - private NoneTelemetryProvider telemetryProvider = mock(NoneTelemetryProvider.class); + private static String ENDPOINTS; + private static NoneTelemetryProvider TELEMETRY_PROVIDER = mock(NoneTelemetryProvider.class); + + @ClassRule + public static final GenericContainer CONTAINER = + new GenericContainer(DockerImageName.parse("bitnami/etcd:3.5.0")) + .waitingFor(Wait.forLogMessage(".*etcd setup finished!.*", 1)) + .withEnv(Collections.singletonMap("ALLOW_NONE_AUTHENTICATION", "yes")); @Before - public void before() { - Mockito.when(telemetryProvider.getService(MetricsCreator.class)) - .thenReturn(new MetricsCreatorNoop()); - TelemetryModule telemetryModule = Mockito.spy(TelemetryModule.class); - Whitebox.setInternalState(telemetryModule, "loadedProvider", telemetryProvider); - Mockito.when(moduleManager.find(TelemetryModule.NAME)).thenReturn(telemetryModule); - String etcdHost = System.getProperty("etcd.host"); - String port = System.getProperty("etcd.port"); - assertTrue(!StringUtil.isEmpty(etcdHost) && !StringUtil.isEmpty(port)); - etcdAddress = etcdHost + ":" + port; + public void setup() { + Mockito.when(TELEMETRY_PROVIDER.getService(MetricsCreator.class)) + .thenReturn(new MetricsCreatorNoop()); + ENDPOINTS = "http://127.0.0.1:" + CONTAINER.getMappedPort(2379); } @Test @@ -160,7 +163,7 @@ public class ITClusterModuleEtcdProviderFunctionalTest { validateServiceInstance(addressB, addressA, remoteInstancesOfB); // unregister A - EtcdClient client = Whitebox.getInternalState(providerA, "client"); + Client client = Whitebox.getInternalState(getClusterRegister(providerA), "client"); client.close(); // only B @@ -176,12 +179,12 @@ public class ITClusterModuleEtcdProviderFunctionalTest { } private ClusterModuleEtcdProvider createProvider(String serviceName, String internalComHost, - int internalComPort) throws ModuleStartException { + int internalComPort) throws ModuleStartException { ClusterModuleEtcdProvider provider = new ClusterModuleEtcdProvider(); ClusterModuleEtcdConfig config = (ClusterModuleEtcdConfig) provider.createConfigBeanIfAbsent(); - config.setHostPort(etcdAddress); + config.setEndpoints(ENDPOINTS); config.setServiceName(serviceName); if (!StringUtil.isEmpty(internalComHost)) { @@ -191,7 +194,12 @@ public class ITClusterModuleEtcdProviderFunctionalTest { if (internalComPort > 0) { config.setInternalComPort(internalComPort); } - provider.setManager(moduleManager); + TelemetryModule telemetryModule = Mockito.spy(TelemetryModule.class); + Whitebox.setInternalState(telemetryModule, "loadedProvider", TELEMETRY_PROVIDER); + ModuleManager manager = mock(ModuleManager.class); + Mockito.when(manager.find(TelemetryModule.NAME)).thenReturn(telemetryModule); + + provider.setManager(manager); provider.prepare(); provider.start(); provider.notifyAfterCompleted(); @@ -211,7 +219,7 @@ public class ITClusterModuleEtcdProviderFunctionalTest { } private List queryRemoteNodes(ModuleProvider provider, int goals, - int cyclic) throws InterruptedException { + int cyclic) throws InterruptedException { do { List instances = getClusterNodesQuery(provider).queryRemoteNodes(); if (instances.size() == goals) { @@ -241,4 +249,5 @@ public class ITClusterModuleEtcdProviderFunctionalTest { assertTrue(selfExist); assertTrue(otherExist); } + } diff --git a/oap-server/server-configuration/configuration-etcd/pom.xml b/oap-server/server-configuration/configuration-etcd/pom.xml index 7a42a43e02..fedf77051e 100644 --- a/oap-server/server-configuration/configuration-etcd/pom.xml +++ b/oap-server/server-configuration/configuration-etcd/pom.xml @@ -34,39 +34,54 @@ - io.netty - netty-codec-dns + io.etcd + jetcd-core + + + + io.grpc + grpc-core + + + + io.grpc + grpc-netty io.netty - netty-codec-http + netty-codec-http2 io.netty - netty-handler + netty-handler-proxy - io.netty - netty-resolver-dns + io.grpc + grpc-protobuf - org.mousio - etcd4j + io.grpc + grpc-stub - com.fasterxml.jackson.module - jackson-module-afterburner + io.grpc + grpc-grpclb org.yaml snakeyaml + + + org.testcontainers + testcontainers + @@ -87,93 +102,9 @@ CI-with-IT - - io.fabric8 - docker-maven-plugin - - all - default - true - IfNotPresent - - - - start - pre-integration-test - - start - - - - - quayio/coreos-etcd:${etcd.version} - etcd-client-integration-test - - - etcd.port:2379 - - - - - - - - /usr/local/bin/etcd - --advertise-client-urls=http://0.0.0.0:2379 - --listen-client-urls=http://0.0.0.0:2379 - - - - - - - - - remove-it-etcd - post-integration-test - - stop - - - - - - - org.codehaus.gmaven - gmaven-plugin - 1.5 - - - add-default-properties - initialize - - execute - - - 2.0 - - project.properties.setProperty('etcd.host', 'localhost') - - log.info("Etcd host is " + project.properties['etcd.host']) - - - - - - org.apache.maven.plugins maven-failsafe-plugin - - - - ${etcd.host} - - - ${etcd.port} - - - diff --git a/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdConfigWatcherRegister.java b/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdConfigWatcherRegister.java index 6123295c4a..44df608cee 100644 --- a/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdConfigWatcherRegister.java +++ b/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdConfigWatcherRegister.java @@ -13,144 +13,65 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.apache.skywalking.oap.server.configuration.etcd; -import java.net.URI; -import java.util.HashSet; -import java.util.Map; +import io.etcd.jetcd.ByteSequence; +import io.etcd.jetcd.Client; +import io.etcd.jetcd.ClientBuilder; +import io.etcd.jetcd.KV; +import io.etcd.jetcd.kv.GetResponse; +import java.nio.charset.Charset; import java.util.Optional; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import mousio.client.promises.ResponsePromise; -import mousio.etcd4j.EtcdClient; -import mousio.etcd4j.promises.EtcdResponsePromise; -import mousio.etcd4j.responses.EtcdErrorCode; -import mousio.etcd4j.responses.EtcdException; -import mousio.etcd4j.responses.EtcdKeysResponse; +import lombok.extern.slf4j.Slf4j; +import org.apache.skywalking.apm.util.StringUtil; import org.apache.skywalking.oap.server.configuration.api.ConfigTable; import org.apache.skywalking.oap.server.configuration.api.ConfigWatcherRegister; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class EtcdConfigWatcherRegister extends ConfigWatcherRegister { - private static final Logger LOGGER = LoggerFactory.getLogger(EtcdConfigWatcherRegister.class); + private final KV client; - /** - * server settings for Etcd configuration - */ - private EtcdServerSettings settings; + public EtcdConfigWatcherRegister(EtcdServerSettings setting) { + super(setting.getPeriod()); + ClientBuilder builder = Client.builder() + .authority(setting.getAuthority()) + .endpoints(setting.getEndpointArray()); - /** - * etcd client. - */ - private final EtcdClient client; - - private final Map listenersByKey; - - private final Map> configItemKeyedByName; - - private final Map> responsePromiseByKey; - - public EtcdConfigWatcherRegister(EtcdServerSettings settings) { - super(settings.getPeriod()); - this.settings = settings; - this.configItemKeyedByName = new ConcurrentHashMap<>(); - this.client = new EtcdClient(EtcdUtils.parse(settings).toArray(new URI[] {})); - this.listenersByKey = new ConcurrentHashMap<>(); - responsePromiseByKey = new ConcurrentHashMap<>(); + if (StringUtil.isNotEmpty(setting.getNamespace())) { + builder.namespace(ByteSequence.from(setting.getNamespace(), Charset.defaultCharset())); + } + if (setting.isAuthentication()) { + builder.user(ByteSequence.from(setting.getUser(), Charset.defaultCharset())) + .password(ByteSequence.from(setting.getPassword(), Charset.defaultCharset())); + } + client = builder.build().getKVClient(); } @Override - public Optional readConfig(Set keys) { - removeUninterestedKeys(keys); - registerKeyListeners(keys); - final ConfigTable table = new ConfigTable(); + public Optional readConfig(final Set keys) { + ConfigTable table = new ConfigTable(); + keys.forEach(e -> { + try { + GetResponse response = client.get(ByteSequence.from(e, Charset.defaultCharset())).get(); - for (Map.Entry> entry : configItemKeyedByName.entrySet()) { - final String key = entry.getKey(); - final Optional value = entry.getValue(); - - if (value.isPresent()) { - table.add(new ConfigTable.ConfigItem(key, value.get())); - } else { - table.add(new ConfigTable.ConfigItem(key, null)); + if (0 == response.getCount()) { + table.add(new ConfigTable.ConfigItem(e, null)); + } else { + response.getKvs().forEach(kv -> table.add(new ConfigTable.ConfigItem( + kv.getKey().toString(Charset.defaultCharset()), + kv.getValue().toString(Charset.defaultCharset()) + ) + )); + } + } catch (Exception exp) { + throw new EtcdConfigException("Failed to read configuration", exp); } - } - + }); return Optional.of(table); } - private void registerKeyListeners(final Set keys) { - for (final String key : keys) { - String dataId = "/" + settings.getGroup() + "/" + key; - if (listenersByKey.containsKey(dataId)) { - continue; - } - - listenersByKey.putIfAbsent(dataId, p -> { - onDataValueChanged(p, dataId); - }); - - try { - EtcdResponsePromise responsePromise = client.get(dataId).waitForChange().send(); - responsePromise.addListener(listenersByKey.get(dataId)); - responsePromiseByKey.putIfAbsent(dataId, responsePromise); - - // the key is newly added, read the config for the first time - EtcdResponsePromise promise = client.get(dataId).send(); - onDataValueChanged(promise, dataId); - } catch (Exception e) { - throw new EtcdConfigException("wait for etcd value change fail", e); - } - } - } - - private void removeUninterestedKeys(final Set interestedKeys) { - final Set uninterestedKeys = new HashSet<>(listenersByKey.keySet()); - uninterestedKeys.removeAll(interestedKeys); - - uninterestedKeys.forEach(k -> { - final ResponsePromise.IsSimplePromiseResponseHandler listener = listenersByKey.remove(k); - if (listener != null) { - responsePromiseByKey.remove(k).removeListener(listener); - } - }); - } - - private void onDataValueChanged(ResponsePromise promise, String dataId) { - String key = getRealKey(dataId, settings.getGroup()); - try { - EtcdKeysResponse.EtcdNode node = promise.get().getNode(); - String value = node.getValue(); - if (LOGGER.isInfoEnabled()) { - LOGGER.info("Etcd config changed: {}: {}", key, node.getValue()); - } - - configItemKeyedByName.put(key, Optional.ofNullable(value)); - } catch (Exception e) { - if (e instanceof EtcdException) { - if (EtcdErrorCode.KeyNotFound == ((EtcdException) e).errorCode) { - configItemKeyedByName.put(key, Optional.empty()); - return; - } - } - throw new EtcdConfigException("wait for value changed fail", e); - } - } - - /** - * get real key in etcd cluster which is removed "/${group}" from the key retrive from etcd. - */ - private String getRealKey(String key, String group) { - int index = key.indexOf(group); - if (index <= 0) { - throw new RuntimeException("the group doesn't match"); - } - String realKey = key.substring(index + group.length() + 1); - return realKey; - } } diff --git a/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdConfigurationProvider.java b/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdConfigurationProvider.java index fef0c4ee0b..77f2b1e713 100644 --- a/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdConfigurationProvider.java +++ b/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdConfigurationProvider.java @@ -13,40 +13,29 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.apache.skywalking.oap.server.configuration.etcd; -import com.google.common.base.Strings; +import lombok.extern.slf4j.Slf4j; +import org.apache.skywalking.apm.util.StringUtil; import org.apache.skywalking.oap.server.configuration.api.AbstractConfigurationProvider; import org.apache.skywalking.oap.server.configuration.api.ConfigWatcherRegister; import org.apache.skywalking.oap.server.library.module.ModuleConfig; import org.apache.skywalking.oap.server.library.module.ModuleStartException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -/** - * Get Configuration from etcd. - */ +@Slf4j public class EtcdConfigurationProvider extends AbstractConfigurationProvider { - - private static final Logger LOGGER = LoggerFactory.getLogger(EtcdConfigurationProvider.class); - - private EtcdServerSettings settings; + private final EtcdServerSettings settings; public EtcdConfigurationProvider() { - settings = new EtcdServerSettings(); + this.settings = new EtcdServerSettings(); } @Override protected ConfigWatcherRegister initConfigReader() throws ModuleStartException { - LOGGER.info("settings: {}", settings); - if (Strings.isNullOrEmpty(settings.getServerAddr())) { - throw new ModuleStartException("Etcd serverAddr cannot be null or empty."); - } - if (Strings.isNullOrEmpty(settings.getGroup())) { - throw new ModuleStartException("Etcd group cannot be null or empty."); + if (StringUtil.isEmpty(settings.getEndpoints())) { + throw new ModuleStartException("Etcd endpoints cannot be null or empty."); } try { diff --git a/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdServerSettings.java b/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdServerSettings.java index 17fb82a5bf..053ce828bb 100644 --- a/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdServerSettings.java +++ b/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdServerSettings.java @@ -13,38 +13,41 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.apache.skywalking.oap.server.configuration.etcd; -import lombok.Getter; -import lombok.Setter; +import com.google.common.base.Strings; +import java.util.Arrays; +import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.ToString; import org.apache.skywalking.oap.server.library.module.ModuleConfig; -/** - * entity wrapps the etcd cluster configuration. - */ +@Data @ToString -@Getter -@Setter +@EqualsAndHashCode(callSuper = true) public class EtcdServerSettings extends ModuleConfig { + private int period; + private String endpoints; + private String namespace; + private String authority; + private String user; + private String password; - private String clusterName = "default"; - /** - * etcd cluster address, like "10.10.10.1:2379, 10.10.10.2:2379,10.10.10.3.2379". - */ - private String serverAddr; + private boolean authentication; - /** - * directory for configuration - */ - private String group; - - /** - * sec for interval refresh config data. - */ - private int period = 60; + public String getNamespace() { + if (Strings.isNullOrEmpty(namespace)) { + return null; + } + if (!namespace.endsWith("/")) { + return namespace + "/"; + } + return namespace; + } + public String[] getEndpointArray() { + return Arrays.stream(endpoints.split("\\s*,\\s*")).toArray(String[]::new); + } } diff --git a/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdUtils.java b/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdUtils.java deleted file mode 100644 index 808b823cef..0000000000 --- a/oap-server/server-configuration/configuration-etcd/src/main/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdUtils.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.apache.skywalking.oap.server.configuration.etcd; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import org.apache.skywalking.oap.server.library.util.Address; -import org.apache.skywalking.oap.server.library.util.ConnectUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * a util for etcd serverAddr parse. - */ -public class EtcdUtils { - - private static final Logger LOGGER = LoggerFactory.getLogger(EtcdUtils.class); - - public EtcdUtils() { - } - - public static List parse(EtcdServerSettings settings) { - List uris = new ArrayList<>(); - try { - LOGGER.info("etcd settings is {}", settings); - List
addressList = ConnectUtils.parse(settings.getServerAddr()); - for (Address address : addressList) { - uris.add(new URI("http", null, address.getHost(), address.getPort(), null, null, null)); - } - } catch (Exception e) { - throw new EtcdConfigException(e.getMessage(), e); - } - - return uris; - } - - public static List parseProp(Properties properties) { - List uris = new ArrayList<>(); - try { - LOGGER.info("etcd server addr is {}", properties); - List
addressList = ConnectUtils.parse(properties.getProperty("serverAddr")); - for (Address address : addressList) { - uris.add(new URI("http", null, address.getHost(), address.getPort(), null, null, null)); - } - } catch (Exception e) { - throw new EtcdConfigException(e.getMessage(), e); - } - - return uris; - } - -} diff --git a/oap-server/server-configuration/configuration-etcd/src/test/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdConfigurationTestProvider.java b/oap-server/server-configuration/configuration-etcd/src/test/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdConfigurationTestProvider.java index c87f84f1ec..b938c5df2f 100644 --- a/oap-server/server-configuration/configuration-etcd/src/test/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdConfigurationTestProvider.java +++ b/oap-server/server-configuration/configuration-etcd/src/test/java/org/apache/skywalking/oap/server/configuration/etcd/EtcdConfigurationTestProvider.java @@ -57,7 +57,7 @@ public class EtcdConfigurationTestProvider extends ModuleProvider { private volatile String testValue; @Override - public void notify(ConfigChangeWatcher.ConfigChangeEvent value) { + public void notify(ConfigChangeEvent value) { LOGGER.info("ConfigChangeWatcher.ConfigChangeEvent: {}", value); if (EventType.DELETE.equals(value.getEventType())) { testValue = null; diff --git a/oap-server/server-configuration/configuration-etcd/src/test/java/org/apache/skywalking/oap/server/configuration/etcd/ITEtcdConfigurationTest.java b/oap-server/server-configuration/configuration-etcd/src/test/java/org/apache/skywalking/oap/server/configuration/etcd/ITEtcdConfigurationTest.java index fa638a85fb..b2072091e7 100644 --- a/oap-server/server-configuration/configuration-etcd/src/test/java/org/apache/skywalking/oap/server/configuration/etcd/ITEtcdConfigurationTest.java +++ b/oap-server/server-configuration/configuration-etcd/src/test/java/org/apache/skywalking/oap/server/configuration/etcd/ITEtcdConfigurationTest.java @@ -18,99 +18,114 @@ package org.apache.skywalking.oap.server.configuration.etcd; +import io.etcd.jetcd.ByteSequence; +import io.etcd.jetcd.Client; +import io.etcd.jetcd.KV; import java.io.FileNotFoundException; import java.io.Reader; -import java.net.URI; -import java.util.List; +import java.nio.charset.Charset; +import java.util.Collections; import java.util.Map; import java.util.Properties; -import mousio.etcd4j.EtcdClient; -import mousio.etcd4j.promises.EtcdResponsePromise; -import mousio.etcd4j.responses.EtcdKeysResponse; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; import org.apache.skywalking.apm.util.PropertyPlaceholderHelper; import org.apache.skywalking.oap.server.library.module.ApplicationConfiguration; +import org.apache.skywalking.oap.server.library.module.ModuleConfigException; import org.apache.skywalking.oap.server.library.module.ModuleManager; +import org.apache.skywalking.oap.server.library.module.ModuleNotFoundException; +import org.apache.skywalking.oap.server.library.module.ModuleStartException; import org.apache.skywalking.oap.server.library.util.CollectionUtils; import org.apache.skywalking.oap.server.library.util.ResourceUtils; -import org.junit.Before; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.DockerImageName; import org.yaml.snakeyaml.Yaml; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +@Slf4j public class ITEtcdConfigurationTest { + @ClassRule + public static final GenericContainer CONTAINER = + new GenericContainer(DockerImageName.parse("bitnami/etcd:3.5.0")) + .waitingFor(Wait.forLogMessage(".*etcd setup finished!.*", 1)) + .withEnv(Collections.singletonMap("ALLOW_NONE_AUTHENTICATION", "yes")); - private static final Logger LOGGER = LoggerFactory.getLogger(ITEtcdConfigurationTest.class); + private static EtcdConfigurationTestProvider PROVIDER; - private final Yaml yaml = new Yaml(); + private static final String TEST_VALUE = "value"; - private EtcdServerSettings settings; + @BeforeClass + public static void beforeClass() throws FileNotFoundException, ModuleConfigException, ModuleNotFoundException, ModuleStartException { + System.setProperty("etcd.endpoint", "http://127.0.0.1:" + CONTAINER.getMappedPort(2379)); - private EtcdConfigurationTestProvider provider; - - private EtcdClient client; - - @Before - public void setUp() throws Exception { final ApplicationConfiguration applicationConfiguration = new ApplicationConfiguration(); loadConfig(applicationConfiguration); final ModuleManager moduleManager = new ModuleManager(); moduleManager.init(applicationConfiguration); - final String etcdHost = System.getProperty("etcd.host"); - final String etcdPort = System.getProperty("etcd.port"); - LOGGER.info("etcdHost: {}, etcdPort: {}", etcdHost, etcdPort); - Properties properties = new Properties(); - properties.setProperty("serverAddr", etcdHost + ":" + etcdPort); + PROVIDER = (EtcdConfigurationTestProvider) moduleManager.find(EtcdConfigurationTestModule.NAME).provider(); - List uris = EtcdUtils.parseProp(properties); - client = new EtcdClient(uris.toArray(new URI[] {})); - - provider = (EtcdConfigurationTestProvider) moduleManager.find(EtcdConfigurationTestModule.NAME).provider(); - - assertNotNull(provider); + assertNotNull(PROVIDER); } @Test(timeout = 20000) public void shouldReadUpdated() throws Exception { - assertNull(provider.watcher.value()); + assertNull(PROVIDER.watcher.value()); - assertTrue(publishConfig("test-module.default.testKey", "skywalking", "500")); + KV client = Client.builder() + .endpoints("http://localhost:" + CONTAINER.getMappedPort(2379)) + .namespace(ByteSequence.from("/skywalking/", Charset.defaultCharset())) + .build() + .getKVClient(); - for (String v = provider.watcher.value(); v == null; v = provider.watcher.value()) { - LOGGER.info("value is : {}", provider.watcher.value()); + client.put( + ByteSequence.from("test-module.default.testKey", Charset.defaultCharset()), + ByteSequence.from(TEST_VALUE, Charset.defaultCharset()) + ).get(); + + for (String v = PROVIDER.watcher.value(); v == null; v = PROVIDER.watcher.value()) { + log.info("value is : {}", PROVIDER.watcher.value()); + TimeUnit.MILLISECONDS.sleep(200L); } - assertEquals("500", provider.watcher.value()); + assertEquals(TEST_VALUE, PROVIDER.watcher.value()); - assertTrue(removeConfig("test-module.default.testKey", "skywalking")); + client.delete(ByteSequence.from("test-module.default.testKey", Charset.defaultCharset())).get(); - for (String v = provider.watcher.value(); v != null; v = provider.watcher.value()) { + for (String v = PROVIDER.watcher.value(); v != null; v = PROVIDER.watcher.value()) { + TimeUnit.MILLISECONDS.sleep(200L); } - assertNull(provider.watcher.value()); + assertNull(PROVIDER.watcher.value()); } @SuppressWarnings("unchecked") - private void loadConfig(ApplicationConfiguration configuration) throws FileNotFoundException { + private static void loadConfig(ApplicationConfiguration configuration) throws FileNotFoundException { + final Yaml yaml = new Yaml(); + Reader applicationReader = ResourceUtils.read("application.yml"); Map>> moduleConfig = yaml.loadAs(applicationReader, Map.class); if (CollectionUtils.isNotEmpty(moduleConfig)) { moduleConfig.forEach((moduleName, providerConfig) -> { if (providerConfig.size() > 0) { - ApplicationConfiguration.ModuleConfiguration moduleConfiguration = configuration.addModule(moduleName); + ApplicationConfiguration.ModuleConfiguration moduleConfiguration = configuration.addModule( + moduleName); providerConfig.forEach((name, propertiesConfig) -> { Properties properties = new Properties(); if (propertiesConfig != null) { propertiesConfig.forEach((key, value) -> { properties.put(key, value); - final Object replaceValue = yaml.load(PropertyPlaceholderHelper.INSTANCE.replacePlaceholders(value + "", properties)); + final Object replaceValue = yaml.load( + PropertyPlaceholderHelper.INSTANCE.replacePlaceholders(value + "", properties)); if (replaceValue != null) { properties.replace(key, replaceValue); } @@ -123,24 +138,8 @@ public class ITEtcdConfigurationTest { } } - private boolean publishConfig(String key, String group, String value) { - try { - client.putDir(group).send().get(); - EtcdResponsePromise promise = client.put(generateKey(key, group), value).send(); - promise.get(); - return true; - } catch (Exception e) { - return false; - } + @AfterClass + public static void teardown() { + CONTAINER.close(); } - - private boolean removeConfig(String key, String group) throws Exception { - client.delete(generateKey(key, group)).send().get(); - return true; - } - - private String generateKey(String key, String group) { - return new StringBuilder("/").append(group).append("/").append(key).toString(); - } - } diff --git a/oap-server/server-configuration/configuration-etcd/src/test/java/org/apache/skywalking/oap/server/configuration/etcd/TestEtcdUtils.java b/oap-server/server-configuration/configuration-etcd/src/test/java/org/apache/skywalking/oap/server/configuration/etcd/TestEtcdUtils.java deleted file mode 100644 index feea4cd814..0000000000 --- a/oap-server/server-configuration/configuration-etcd/src/test/java/org/apache/skywalking/oap/server/configuration/etcd/TestEtcdUtils.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.apache.skywalking.oap.server.configuration.etcd; - -import java.net.URI; -import java.util.List; -import java.util.Properties; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -public class TestEtcdUtils { - - private EtcdServerSettings settings; - - private Properties properties; - - @Before - public void setUp() { - settings = new EtcdServerSettings(); - settings.setServerAddr("localhost:2379"); - properties = new Properties(); - properties.setProperty("serverAddr", "localhost:2379"); - } - - @Test - public void testParse() { - List list = EtcdUtils.parse(settings); - Assert.assertEquals(1, list.size()); - URI uri = list.get(0); - Assert.assertEquals("http", uri.getScheme()); - Assert.assertEquals("localhost", uri.getHost()); - Assert.assertEquals(2379, uri.getPort()); - } - - @Test - public void testProp() { - List list = EtcdUtils.parseProp(properties); - Assert.assertEquals(1, list.size()); - URI uri = list.get(0); - Assert.assertEquals("http", uri.getScheme()); - Assert.assertEquals("localhost", uri.getHost()); - Assert.assertEquals(2379, uri.getPort()); - } -} diff --git a/oap-server/server-configuration/configuration-etcd/src/test/resources/application.yml b/oap-server/server-configuration/configuration-etcd/src/test/resources/application.yml index e4e19817e5..8cbe532d76 100755 --- a/oap-server/server-configuration/configuration-etcd/src/test/resources/application.yml +++ b/oap-server/server-configuration/configuration-etcd/src/test/resources/application.yml @@ -22,12 +22,8 @@ test-module: configuration: etcd: # Etcd Server Host - serverAddr: ${etcd.host}:${etcd.port} - # Etcd Server Port - port: ${etcd.port} + endpoints: ${etcd.endpoint} # Etcd Configuration Group - group: 'skywalking' + namespace: /skywalking/ # Unit seconds, sync period. Default fetch every 60 seconds. period: 1 - # the name of current cluster, set the name if you want to upstream system known. - clusterName: "default" diff --git a/oap-server/server-library/library-client/pom.xml b/oap-server/server-library/library-client/pom.xml index a712bf6b6f..b39ba7b6a8 100755 --- a/oap-server/server-library/library-client/pom.xml +++ b/oap-server/server-library/library-client/pom.xml @@ -47,6 +47,18 @@ io.grpc grpc-netty + + io.netty + netty-codec-http2 + + + io.netty + netty-handler + + + io.netty + netty-handler-proxy + com.google.code.gson gson diff --git a/oap-server/server-library/library-server/pom.xml b/oap-server/server-library/library-server/pom.xml index 25a3446b9f..a67e47d3c8 100644 --- a/oap-server/server-library/library-server/pom.xml +++ b/oap-server/server-library/library-server/pom.xml @@ -59,5 +59,21 @@ org.eclipse.jetty jetty-servlet + + io.netty + netty-handler + + + io.netty + netty-codec + + + io.netty + netty-codec-http + + + io.netty + netty-codec-http2 + diff --git a/tools/dependencies/known-oap-backend-dependencies-es7.txt b/tools/dependencies/known-oap-backend-dependencies-es7.txt index d412541283..8e4b67795b 100755 --- a/tools/dependencies/known-oap-backend-dependencies-es7.txt +++ b/tools/dependencies/known-oap-backend-dependencies-es7.txt @@ -41,7 +41,7 @@ elasticsearch-rest-high-level-client-7.10.2.jar elasticsearch-secure-sm-7.10.2.jar elasticsearch-x-content-7.10.2.jar error_prone_annotations-2.3.2.jar -etcd4j-2.18.0.jar +failsafe-2.3.4.jar failureaccess-1.0.1.jar flatbuffers-java-1.12.0.jar freemarker-2.3.28.jar @@ -51,6 +51,7 @@ groovy-3.0.3.jar grpc-api-1.32.1.jar grpc-context-1.32.1.jar grpc-core-1.32.1.jar +grpc-grpclb-1.32.1.jar grpc-netty-1.32.1.jar grpc-protobuf-1.32.1.jar grpc-protobuf-lite-1.32.1.jar @@ -81,6 +82,9 @@ javassist-3.25.0-GA.jar javax.inject-1.jar javax.servlet-api-3.1.0.jar jcl-over-slf4j-1.7.30.jar +jetcd-common-0.5.3.jar +jetcd-core-0.5.3.jar +jetcd-resolver-0.5.3.jar jetty-http-9.4.40.v20210413.jar jetty-io-9.4.40.v20210413.jar jetty-security-9.4.40.v20210413.jar @@ -92,7 +96,6 @@ jna-5.5.0.jar joda-time-2.10.5.jar jopt-simple-4.6.jar jose4j-0.7.6.jar -json-flattener-0.6.0.jar jsr305-3.0.2.jar kafka-clients-2.4.1.jar kotlin-reflect-1.1.1.jar @@ -120,7 +123,6 @@ lucene-spatial3d-8.7.0.jar lucene-suggest-8.7.0.jar lz4-java-1.6.0.jar mapper-extras-client-7.10.2.jar -minimal-json-0.9.5.jar moshi-1.5.0.jar msgpack-core-0.8.16.jar mvel2-2.4.8.Final.jar @@ -129,19 +131,17 @@ nacos-client-1.4.2.jar nacos-common-1.4.2.jar netty-buffer-4.1.65.Final.jar netty-codec-4.1.65.Final.jar -netty-codec-dns-4.1.65.Final.jar netty-codec-http-4.1.65.Final.jar -netty-codec-http2-4.1.51.Final.jar -netty-codec-socks-4.1.51.Final.jar +netty-codec-http2-4.1.65.Final.jar +netty-codec-socks-4.1.65.Final.jar netty-common-4.1.65.Final.jar netty-handler-4.1.65.Final.jar -netty-handler-proxy-4.1.51.Final.jar +netty-handler-proxy-4.1.65.Final.jar netty-resolver-4.1.65.Final.jar -netty-resolver-dns-4.1.65.Final.jar netty-tcnative-boringssl-static-2.0.39.Final.jar netty-transport-4.1.65.Final.jar -netty-transport-native-epoll-4.1.45.Final.jar -netty-transport-native-unix-common-4.1.45.Final.jar +netty-transport-native-epoll-4.1.65.Final.jar +netty-transport-native-unix-common-4.1.65.Final.jar okhttp-3.14.9.jar okio-1.17.2.jar parent-join-client-7.10.2.jar diff --git a/tools/dependencies/known-oap-backend-dependencies.txt b/tools/dependencies/known-oap-backend-dependencies.txt index a8b0cbfdf8..16d38cdf40 100755 --- a/tools/dependencies/known-oap-backend-dependencies.txt +++ b/tools/dependencies/known-oap-backend-dependencies.txt @@ -39,7 +39,7 @@ elasticsearch-rest-high-level-client-6.3.2.jar elasticsearch-secure-sm-6.3.2.jar elasticsearch-x-content-6.3.2.jar error_prone_annotations-2.3.2.jar -etcd4j-2.18.0.jar +failsafe-2.3.4.jar failureaccess-1.0.1.jar flatbuffers-java-1.12.0.jar freemarker-2.3.28.jar @@ -49,6 +49,7 @@ groovy-3.0.3.jar grpc-api-1.32.1.jar grpc-context-1.32.1.jar grpc-core-1.32.1.jar +grpc-grpclb-1.32.1.jar grpc-netty-1.32.1.jar grpc-protobuf-1.32.1.jar grpc-protobuf-lite-1.32.1.jar @@ -79,6 +80,9 @@ javassist-3.25.0-GA.jar javax.inject-1.jar javax.servlet-api-3.1.0.jar jcl-over-slf4j-1.7.30.jar +jetcd-common-0.5.3.jar +jetcd-core-0.5.3.jar +jetcd-resolver-0.5.3.jar jetty-http-9.4.40.v20210413.jar jetty-io-9.4.40.v20210413.jar jetty-security-9.4.40.v20210413.jar @@ -90,7 +94,6 @@ jna-4.5.1.jar joda-time-2.10.5.jar jopt-simple-4.6.jar jose4j-0.7.6.jar -json-flattener-0.6.0.jar jsr305-3.0.2.jar kafka-clients-2.4.1.jar kotlin-reflect-1.1.1.jar @@ -117,7 +120,6 @@ lucene-spatial-extras-7.3.1.jar lucene-spatial3d-7.3.1.jar lucene-suggest-7.3.1.jar lz4-java-1.6.0.jar -minimal-json-0.9.5.jar moshi-1.5.0.jar msgpack-core-0.8.16.jar mvel2-2.4.8.Final.jar @@ -126,19 +128,17 @@ nacos-client-1.4.2.jar nacos-common-1.4.2.jar netty-buffer-4.1.65.Final.jar netty-codec-4.1.65.Final.jar -netty-codec-dns-4.1.65.Final.jar netty-codec-http-4.1.65.Final.jar -netty-codec-http2-4.1.51.Final.jar -netty-codec-socks-4.1.51.Final.jar +netty-codec-http2-4.1.65.Final.jar +netty-codec-socks-4.1.65.Final.jar netty-common-4.1.65.Final.jar netty-handler-4.1.65.Final.jar -netty-handler-proxy-4.1.51.Final.jar +netty-handler-proxy-4.1.65.Final.jar netty-resolver-4.1.65.Final.jar -netty-resolver-dns-4.1.65.Final.jar netty-tcnative-boringssl-static-2.0.39.Final.jar netty-transport-4.1.65.Final.jar -netty-transport-native-epoll-4.1.45.Final.jar -netty-transport-native-unix-common-4.1.45.Final.jar +netty-transport-native-epoll-4.1.65.Final.jar +netty-transport-native-unix-common-4.1.65.Final.jar okhttp-3.14.9.jar okio-1.17.2.jar parent-join-client-6.3.2.jar