parent
71f3e8618b
commit
a70a2b236e
|
|
@ -318,8 +318,11 @@ The text of each license is the standard Apache 2.0 license.
|
||||||
proto files from prometheus/client_model: https://github.com/prometheus/client_model Apache 2.0
|
proto files from prometheus/client_model: https://github.com/prometheus/client_model Apache 2.0
|
||||||
proto files from lyft/protoc-gen-validate: https://github.com/lyft/protoc-gen-validate Apache 2.0
|
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
|
proto files from gogo/googleapis: https://github.com/gogo/googleapis 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
|
sundrio 0.9.2: https://github.com/sundrio/sundrio Apache 2.0
|
||||||
Ctripcorp: apollo 1.4.0: https://github.com/ctripcorp/apollo Apache 2.0
|
Ctripcorp: apollo 1.4.0: https://github.com/ctripcorp/apollo Apache 2.0
|
||||||
|
etcd4j 2.17.0: https://github.com/jurmous/etcd4j Apache 2.0
|
||||||
|
|
||||||
========================================================================
|
========================================================================
|
||||||
MIT licenses
|
MIT licenses
|
||||||
|
|
@ -335,6 +338,7 @@ The text of each license is also included at licenses/LICENSE-[project].txt.
|
||||||
jopt-simple 5.0.2: https://github.com/jopt-simple/jopt-simple , MIT
|
jopt-simple 5.0.2: https://github.com/jopt-simple/jopt-simple , MIT
|
||||||
bcpkix-jdk15on 1.55: http://www.bouncycastle.org/licence.html , MIT
|
bcpkix-jdk15on 1.55: http://www.bouncycastle.org/licence.html , MIT
|
||||||
bcprov-jdk15on 1.55: http://www.bouncycastle.org/licence.html , MIT
|
bcprov-jdk15on 1.55: http://www.bouncycastle.org/licence.html , MIT
|
||||||
|
minimao-json 0.9.5: https://github.com/ralfstx/minimal-json, MIT
|
||||||
|
|
||||||
========================================================================
|
========================================================================
|
||||||
BSD licenses
|
BSD licenses
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
Copyright (c) 2013, 2014 EclipseSource
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
@ -49,7 +49,7 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
generateClusterConsul() {
|
generateClusterConsul() {
|
||||||
cat <<EOT >> ${var_application_file}
|
cat <<EOT >> ${var_application_file}
|
||||||
cluster:
|
cluster:
|
||||||
consul:
|
consul:
|
||||||
serviceName: \${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
|
serviceName: \${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
|
||||||
|
|
@ -58,6 +58,16 @@ cluster:
|
||||||
EOT
|
EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generateClusterEtcd() {
|
||||||
|
cat <<EOT >> ${var_application_file}
|
||||||
|
cluster:
|
||||||
|
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}
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
|
||||||
generateStorageElastisearch() {
|
generateStorageElastisearch() {
|
||||||
cat <<EOT >> ${var_application_file}
|
cat <<EOT >> ${var_application_file}
|
||||||
storage:
|
storage:
|
||||||
|
|
@ -120,7 +130,7 @@ generateApplicationYaml() {
|
||||||
# validate
|
# validate
|
||||||
[[ -z "$SW_CLUSTER" ]] && [[ -z "$SW_STORAGE" ]] && { echo "Error: please specify \"SW_CLUSTER\" \"SW_STORAGE\""; exit 1; }
|
[[ -z "$SW_CLUSTER" ]] && [[ -z "$SW_STORAGE" ]] && { echo "Error: please specify \"SW_CLUSTER\" \"SW_STORAGE\""; exit 1; }
|
||||||
|
|
||||||
validateVariables "SW_CLUSTER" "$SW_CLUSTER" "standalone zookeeper kubernetes consul"
|
validateVariables "SW_CLUSTER" "$SW_CLUSTER" "standalone zookeeper kubernetes consul etcd"
|
||||||
|
|
||||||
validateVariables "SW_STORAGE" "$SW_STORAGE" "elasticsearch h2 mysql"
|
validateVariables "SW_STORAGE" "$SW_STORAGE" "elasticsearch h2 mysql"
|
||||||
|
|
||||||
|
|
@ -131,6 +141,7 @@ generateApplicationYaml() {
|
||||||
zookeeper) generateClusterZookeeper;;
|
zookeeper) generateClusterZookeeper;;
|
||||||
kubernetes) generateClusterK8s;;
|
kubernetes) generateClusterK8s;;
|
||||||
consul) generateClusterConsul;;
|
consul) generateClusterConsul;;
|
||||||
|
etcd) generateClusterEtcd;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
#generate core
|
#generate core
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,8 @@
|
||||||
<apollo.version>1.4.0</apollo.version>
|
<apollo.version>1.4.0</apollo.version>
|
||||||
<maven-docker-plugin.version>0.30.0</maven-docker-plugin.version>
|
<maven-docker-plugin.version>0.30.0</maven-docker-plugin.version>
|
||||||
<nacos.version>1.0.0</nacos.version>
|
<nacos.version>1.0.0</nacos.version>
|
||||||
|
<etcd4j.version>2.17.0</etcd4j.version>
|
||||||
|
<etcd.version>v3.2.3</etcd.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
@ -371,6 +373,11 @@
|
||||||
<artifactId>nacos-client</artifactId>
|
<artifactId>nacos-client</artifactId>
|
||||||
<version>${nacos.version}</version>
|
<version>${nacos.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mousio</groupId>
|
||||||
|
<artifactId>etcd4j</artifactId>
|
||||||
|
<version>${etcd4j.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,180 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ 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.
|
||||||
|
~
|
||||||
|
-->
|
||||||
|
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>server-cluster-plugin</artifactId>
|
||||||
|
<groupId>org.apache.skywalking</groupId>
|
||||||
|
<version>6.2.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>cluster-etcd-plugin</artifactId>
|
||||||
|
|
||||||
|
<name>cluster-etcd-plugin</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.skywalking</groupId>
|
||||||
|
<artifactId>server-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-handler</artifactId>
|
||||||
|
<version>4.1.27.Final</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-resolver-dns</artifactId>
|
||||||
|
<version>4.1.27.Final</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mousio</groupId>
|
||||||
|
<artifactId>etcd4j</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>netty-codec-dns</artifactId>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
</exclusion>
|
||||||
|
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>netty-codec-dns</artifactId>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
</exclusion>
|
||||||
|
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>netty-codec-http</artifactId>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
</exclusion>
|
||||||
|
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>netty-handler</artifactId>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
</exclusion>
|
||||||
|
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>netty-resolver-dns</artifactId>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
</exclusion>
|
||||||
|
|
||||||
|
<exclusion>
|
||||||
|
<groupId>com.fasterxml.jackson.module</groupId>
|
||||||
|
<artifactId>jackson-module-afterburner</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.module</groupId>
|
||||||
|
<artifactId>jackson-module-afterburner</artifactId>
|
||||||
|
<version>2.9.5</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>CI-with-IT</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>io.fabric8</groupId>
|
||||||
|
<artifactId>docker-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<sourceMode>all</sourceMode>
|
||||||
|
<logDate>default</logDate>
|
||||||
|
<verbose>true</verbose>
|
||||||
|
<imagePullPolicy>IfNotPresent</imagePullPolicy>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>start</id>
|
||||||
|
<phase>pre-integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>start</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<images>
|
||||||
|
<image>
|
||||||
|
<name>quayio/coreos-etcd:${etcd.version}</name>
|
||||||
|
<alias>etcd-client-integration-test</alias>
|
||||||
|
<run>
|
||||||
|
<ports>
|
||||||
|
<port>+etcd.host:etcd.port:2379</port>
|
||||||
|
</ports>
|
||||||
|
<wait>
|
||||||
|
<time>20000</time>
|
||||||
|
</wait>
|
||||||
|
<entrypoint>
|
||||||
|
<!-- exec form -->
|
||||||
|
<exec>
|
||||||
|
<arg>/usr/local/bin/etcd</arg>
|
||||||
|
<arg>--advertise-client-urls=http://0.0.0.0:2379</arg>
|
||||||
|
<arg>--listen-client-urls=http://0.0.0.0:2379</arg>
|
||||||
|
</exec>
|
||||||
|
</entrypoint>
|
||||||
|
</run>
|
||||||
|
</image>
|
||||||
|
</images>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>remove-it-etcd</id>
|
||||||
|
<phase>post-integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>stop</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<etcd.host>
|
||||||
|
${etcd.host}
|
||||||
|
</etcd.host>
|
||||||
|
<etcd.port>
|
||||||
|
${etcd.port}
|
||||||
|
</etcd.port>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>integration-test</goal>
|
||||||
|
<goal>verify</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* 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 lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Alan Lau
|
||||||
|
*/
|
||||||
|
public class ClusterModuleEtcdConfig extends ModuleConfig {
|
||||||
|
|
||||||
|
@Setter @Getter private String serviceName;
|
||||||
|
@Setter @Getter private String hostPort;
|
||||||
|
@Setter @Getter private boolean isSSL;
|
||||||
|
@Setter @Getter private String internalComHost;
|
||||||
|
@Setter @Getter private int internalComPort = -1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* 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.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;
|
||||||
|
import org.apache.skywalking.oap.server.core.cluster.ClusterRegister;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleConfig;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleDefine;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleProvider;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleStartException;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* etcd Provider.
|
||||||
|
*
|
||||||
|
* @author Alan Lau
|
||||||
|
*/
|
||||||
|
public class ClusterModuleEtcdProvider extends ModuleProvider {
|
||||||
|
|
||||||
|
private final ClusterModuleEtcdConfig config;
|
||||||
|
|
||||||
|
private EtcdClient client;
|
||||||
|
|
||||||
|
public ClusterModuleEtcdProvider() {
|
||||||
|
super();
|
||||||
|
this.config = new ClusterModuleEtcdConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public String name() {
|
||||||
|
return "etcd";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public Class<? extends ModuleDefine> module() {
|
||||||
|
return ClusterModule.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public ModuleConfig createConfigBeanIfAbsent() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void prepare() throws ServiceNotProvidedException, ModuleStartException {
|
||||||
|
|
||||||
|
List<URI> uris = EtcdUtils.parse(config);
|
||||||
|
|
||||||
|
//TODO check isSSL
|
||||||
|
client = new EtcdClient(uris.toArray(new URI[] {}));
|
||||||
|
EtcdCoordinator coordinator = new EtcdCoordinator(config, client);
|
||||||
|
this.registerServiceImplementation(ClusterRegister.class, coordinator);
|
||||||
|
this.registerServiceImplementation(ClusterNodesQuery.class, coordinator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void start() throws ServiceNotProvidedException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void notifyAfterCompleted() throws ServiceNotProvidedException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public String[] requiredModules() {
|
||||||
|
return new String[] {CoreModule.NAME};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
* 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 com.google.common.base.Strings;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
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 org.apache.skywalking.oap.server.core.cluster.ClusterNodesQuery;
|
||||||
|
import org.apache.skywalking.oap.server.core.cluster.ClusterRegister;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Alan Lau
|
||||||
|
*/
|
||||||
|
public class EtcdCoordinator implements ClusterRegister, ClusterNodesQuery {
|
||||||
|
|
||||||
|
private ClusterModuleEtcdConfig config;
|
||||||
|
|
||||||
|
private EtcdClient client;
|
||||||
|
|
||||||
|
private volatile Address selfAddress;
|
||||||
|
|
||||||
|
private final String serviceName;
|
||||||
|
|
||||||
|
private ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
|
||||||
|
private static final Integer KEY_TTL = 45;
|
||||||
|
|
||||||
|
public EtcdCoordinator(ClusterModuleEtcdConfig config, EtcdClient client) {
|
||||||
|
this.config = config;
|
||||||
|
this.client = client;
|
||||||
|
this.serviceName = config.getServiceName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public List<RemoteInstance> queryRemoteNodes() {
|
||||||
|
|
||||||
|
List<RemoteInstance> res = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
EtcdKeysResponse response = client.get(serviceName + "/").send().get();
|
||||||
|
List<EtcdKeysResponse.EtcdNode> nodes = response.getNode().getNodes();
|
||||||
|
|
||||||
|
Gson gson = new Gson();
|
||||||
|
if (nodes != null) {
|
||||||
|
nodes.forEach(node -> {
|
||||||
|
EtcdEndpoint endpoint = gson.fromJson(node.getValue(), EtcdEndpoint.class);
|
||||||
|
res.add(new RemoteInstance(new Address(endpoint.getHost(), endpoint.getPort(), true)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void registerRemote(RemoteInstance remoteInstance) throws ServiceRegisterException {
|
||||||
|
|
||||||
|
if (needUsingInternalAddr()) {
|
||||||
|
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();
|
||||||
|
try {
|
||||||
|
client.putDir(serviceName).send();
|
||||||
|
String key = buildKey(serviceName, selfAddress, remoteInstance);
|
||||||
|
String json = new Gson().toJson(endpoint);
|
||||||
|
EtcdResponsePromise<EtcdKeysResponse> promise = client.put(key, json).ttl(KEY_TTL).send();
|
||||||
|
//check register.
|
||||||
|
promise.get();
|
||||||
|
renew(client, key, json);
|
||||||
|
} catch (Exception 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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}, 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 boolean needUsingInternalAddr() {
|
||||||
|
return !Strings.isNullOrEmpty(config.getInternalComHost()) && config.getInternalComPort() > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* 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.io.Serializable;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* an instance json to register to etcd.
|
||||||
|
*
|
||||||
|
* @author Alan Lau
|
||||||
|
*/
|
||||||
|
public class EtcdEndpoint implements Serializable {
|
||||||
|
|
||||||
|
@Setter @Getter private String serviceName;
|
||||||
|
|
||||||
|
@Setter @Getter private String host;
|
||||||
|
|
||||||
|
@Setter @Getter private int port;
|
||||||
|
|
||||||
|
public EtcdEndpoint(Builder builder) {
|
||||||
|
setServiceName(builder.serviceName);
|
||||||
|
setHost(builder.host);
|
||||||
|
setPort(builder.port);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
private String serviceName;
|
||||||
|
|
||||||
|
private String host;
|
||||||
|
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
public Builder serviceName(String serviceName) {
|
||||||
|
this.serviceName = serviceName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder host(String host) {
|
||||||
|
this.host = host;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder port(int port) {
|
||||||
|
this.port = port;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EtcdEndpoint build() {
|
||||||
|
return new EtcdEndpoint(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Alan Lau
|
||||||
|
*/
|
||||||
|
public class EtcdUtils {
|
||||||
|
|
||||||
|
public EtcdUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<URI> parse(ClusterModuleEtcdConfig config) throws ModuleStartException {
|
||||||
|
List<URI> uris = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
List<Address> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
org.apache.skywalking.oap.server.cluster.plugin.etcd.ClusterModuleEtcdProvider
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
* 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.List;
|
||||||
|
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||||
|
import org.apache.skywalking.oap.server.core.cluster.ClusterModule;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleConfig;
|
||||||
|
import org.apache.skywalking.oap.server.library.module.ModuleStartException;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.powermock.api.mockito.PowerMockito;
|
||||||
|
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
import org.powermock.reflect.Whitebox;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Alan Lau
|
||||||
|
*/
|
||||||
|
@RunWith(PowerMockRunner.class)
|
||||||
|
@PrepareForTest(EtcdUtils.class)
|
||||||
|
@PowerMockIgnore("javax.management.*")
|
||||||
|
public class ClusterModuleEtcdProviderTest {
|
||||||
|
|
||||||
|
private ClusterModuleEtcdProvider provider = new ClusterModuleEtcdProvider();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void name() {
|
||||||
|
assertEquals("etcd", provider.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void module() {
|
||||||
|
assertEquals(ClusterModule.class, provider.module());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createConfigBeanIfAbsent() {
|
||||||
|
ModuleConfig moduleConfig = provider.createConfigBeanIfAbsent();
|
||||||
|
assertTrue(moduleConfig instanceof ClusterModuleEtcdConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ModuleStartException.class)
|
||||||
|
public void prepareWithNonHost() throws Exception {
|
||||||
|
provider.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void prepare() throws Exception {
|
||||||
|
PowerMockito.mockStatic(EtcdUtils.class);
|
||||||
|
ClusterModuleEtcdConfig etcdConfig = new ClusterModuleEtcdConfig();
|
||||||
|
etcdConfig.setHostPort("10.0.0.1:1000,10.0.0.2:1001");
|
||||||
|
Whitebox.setInternalState(provider, "config", etcdConfig);
|
||||||
|
provider.prepare();
|
||||||
|
|
||||||
|
List<URI> uris = mock(List.class);
|
||||||
|
PowerMockito.when(EtcdUtils.parse(etcdConfig)).thenReturn(uris);
|
||||||
|
ArgumentCaptor<ClusterModuleEtcdConfig> addressCaptor = ArgumentCaptor.forClass(ClusterModuleEtcdConfig.class);
|
||||||
|
PowerMockito.verifyStatic();
|
||||||
|
EtcdUtils.parse(addressCaptor.capture());
|
||||||
|
ClusterModuleEtcdConfig cfg = addressCaptor.getValue();
|
||||||
|
assertEquals(etcdConfig.getHostPort(), cfg.getHostPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void prepareSingle() throws Exception {
|
||||||
|
PowerMockito.mockStatic(EtcdUtils.class);
|
||||||
|
ClusterModuleEtcdConfig etcdConfig = new ClusterModuleEtcdConfig();
|
||||||
|
etcdConfig.setHostPort("10.0.0.1:1000");
|
||||||
|
Whitebox.setInternalState(provider, "config", etcdConfig);
|
||||||
|
provider.prepare();
|
||||||
|
|
||||||
|
List<URI> uris = mock(List.class);
|
||||||
|
PowerMockito.when(EtcdUtils.parse(etcdConfig)).thenReturn(uris);
|
||||||
|
ArgumentCaptor<ClusterModuleEtcdConfig> addressCaptor = ArgumentCaptor.forClass(ClusterModuleEtcdConfig.class);
|
||||||
|
PowerMockito.verifyStatic();
|
||||||
|
EtcdUtils.parse(addressCaptor.capture());
|
||||||
|
ClusterModuleEtcdConfig cfg = addressCaptor.getValue();
|
||||||
|
assertEquals(etcdConfig.getHostPort(), cfg.getHostPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void start() {
|
||||||
|
provider.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void notifyAfterCompleted() {
|
||||||
|
provider.notifyAfterCompleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void requiredModules() {
|
||||||
|
String[] modules = provider.requiredModules();
|
||||||
|
assertArrayEquals(new String[] {CoreModule.NAME}, modules);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,194 @@
|
||||||
|
/*
|
||||||
|
* 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 com.google.gson.Gson;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import mousio.etcd4j.EtcdClient;
|
||||||
|
import mousio.etcd4j.promises.EtcdResponsePromise;
|
||||||
|
import mousio.etcd4j.requests.EtcdKeyGetRequest;
|
||||||
|
import mousio.etcd4j.requests.EtcdKeyPutRequest;
|
||||||
|
import mousio.etcd4j.responses.EtcdKeysResponse;
|
||||||
|
import org.apache.skywalking.oap.server.core.cluster.RemoteInstance;
|
||||||
|
import org.apache.skywalking.oap.server.core.remote.client.Address;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.powermock.api.mockito.PowerMockito;
|
||||||
|
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.mockito.Matchers.anyInt;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Alan Lau
|
||||||
|
*/
|
||||||
|
@RunWith(PowerMockRunner.class)
|
||||||
|
@PrepareForTest(EtcdKeysResponse.class)
|
||||||
|
@PowerMockIgnore("javax.management.*")
|
||||||
|
public class EtcdCoordinatorTest {
|
||||||
|
|
||||||
|
private ClusterModuleEtcdConfig etcdConfig = new ClusterModuleEtcdConfig();
|
||||||
|
|
||||||
|
private EtcdClient client;
|
||||||
|
|
||||||
|
private EtcdCoordinator coordinator;
|
||||||
|
|
||||||
|
private Gson gson = new Gson();
|
||||||
|
|
||||||
|
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 static final String SERVICE_NAME = "my-service";
|
||||||
|
|
||||||
|
private EtcdResponsePromise<EtcdKeysResponse> getPromise, putPromise;
|
||||||
|
|
||||||
|
private EtcdKeysResponse response;
|
||||||
|
|
||||||
|
private EtcdKeyPutRequest putRequest = mock(EtcdKeyPutRequest.class);
|
||||||
|
|
||||||
|
private EtcdKeyGetRequest getRequest = mock(EtcdKeyGetRequest.class);
|
||||||
|
|
||||||
|
private EtcdKeyPutRequest putDirRequest = mock(EtcdKeyPutRequest.class);
|
||||||
|
|
||||||
|
private EtcdResponsePromise<EtcdKeysResponse> putDirPromise;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private List<EtcdKeysResponse.EtcdNode> list = mock(List.class);
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
etcdConfig.setServiceName(SERVICE_NAME);
|
||||||
|
|
||||||
|
client = mock(EtcdClient.class);
|
||||||
|
PowerMockito.whenNew(EtcdClient.class).withAnyArguments().thenReturn(client);
|
||||||
|
client = new EtcdClient("http://10.0.0.1:1000", "http://10.0.0.2:2000");
|
||||||
|
coordinator = new EtcdCoordinator(etcdConfig, client);
|
||||||
|
|
||||||
|
putPromise = (EtcdResponsePromise<EtcdKeysResponse>)mock(EtcdResponsePromise.class);
|
||||||
|
getPromise = (EtcdResponsePromise<EtcdKeysResponse>)mock(EtcdResponsePromise.class);
|
||||||
|
putDirPromise = (EtcdResponsePromise<EtcdKeysResponse>)mock(EtcdResponsePromise.class);
|
||||||
|
|
||||||
|
PowerMockito.when(client.putDir(anyString())).thenReturn(putDirRequest);
|
||||||
|
PowerMockito.when(putDirRequest.ttl(anyInt())).thenReturn(putDirRequest);
|
||||||
|
PowerMockito.when(putDirRequest.send()).thenReturn(putDirPromise);
|
||||||
|
PowerMockito.when(client.put(anyString(), anyString())).thenReturn(putRequest);
|
||||||
|
PowerMockito.when(putRequest.ttl(anyInt())).thenReturn(putRequest);
|
||||||
|
PowerMockito.when(putRequest.send()).thenReturn(putPromise);
|
||||||
|
PowerMockito.when(client.get(anyString())).thenReturn(getRequest);
|
||||||
|
PowerMockito.when(getRequest.send()).thenReturn(getPromise);
|
||||||
|
|
||||||
|
response = PowerMockito.mock(EtcdKeysResponse.class);
|
||||||
|
|
||||||
|
response = PowerMockito.mock(EtcdKeysResponse.class);
|
||||||
|
when(putPromise.get()).thenReturn(response);
|
||||||
|
when(getPromise.get()).thenReturn(response);
|
||||||
|
when(putDirPromise.get()).thenReturn(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void queryRemoteNodesWithNonOrEmpty() {
|
||||||
|
EtcdKeysResponse.EtcdNode node = PowerMockito.mock(EtcdKeysResponse.EtcdNode.class);
|
||||||
|
when(response.getNode()).thenReturn(node);
|
||||||
|
when(node.getValue()).thenReturn("{}");
|
||||||
|
assertEquals(0, coordinator.queryRemoteNodes().size());
|
||||||
|
assertEquals(0, coordinator.queryRemoteNodes().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void queryRemoteNodes() {
|
||||||
|
registerSelfRemote();
|
||||||
|
|
||||||
|
EtcdKeysResponse.EtcdNode node = PowerMockito.mock(EtcdKeysResponse.EtcdNode.class);
|
||||||
|
EtcdKeysResponse.EtcdNode node1 = PowerMockito.mock(EtcdKeysResponse.EtcdNode.class);
|
||||||
|
|
||||||
|
when(response.getNode()).thenReturn(node);
|
||||||
|
list = new ArrayList<>();
|
||||||
|
List list1 = Mockito.spy(list);
|
||||||
|
list1.add(node1);
|
||||||
|
when(node.getNodes()).thenReturn(list1);
|
||||||
|
when(node1.getValue()).thenReturn("{\"serviceId\":\"my-service\",\"host\":\"10.0.0.2\",\"port\":1001}");
|
||||||
|
List<RemoteInstance> remoteInstances = coordinator.queryRemoteNodes();
|
||||||
|
assertEquals(1, remoteInstances.size());
|
||||||
|
|
||||||
|
RemoteInstance selfInstance = remoteInstances.get(0);
|
||||||
|
velidate(selfRemoteAddress, selfInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void registerRemote() {
|
||||||
|
registerRemote(remoteAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void registerSelfRemote() {
|
||||||
|
registerRemote(selfRemoteAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void registerRemoteUsingInternal() {
|
||||||
|
etcdConfig.setInternalComHost(internalAddress.getHost());
|
||||||
|
etcdConfig.setInternalComPort(internalAddress.getPort());
|
||||||
|
registerRemote(internalAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void velidate(Address originArress, RemoteInstance instance) {
|
||||||
|
Address instanceAddress = instance.getAddress();
|
||||||
|
assertEquals(originArress.getHost(), instanceAddress.getHost());
|
||||||
|
assertEquals(originArress.getPort(), instanceAddress.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerRemote(Address address) {
|
||||||
|
coordinator.registerRemote(new RemoteInstance(address));
|
||||||
|
EtcdEndpoint endpoint = afterRegister().get(0);
|
||||||
|
verifyRegistration(address, endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<EtcdEndpoint> afterRegister() {
|
||||||
|
ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
|
||||||
|
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||||
|
verify(client).put(nameCaptor.capture(), argumentCaptor.capture());
|
||||||
|
EtcdEndpoint endpoint = gson.fromJson(argumentCaptor.getValue(), EtcdEndpoint.class);
|
||||||
|
List<EtcdEndpoint> list = new ArrayList<>();
|
||||||
|
list.add(endpoint);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyRegistration(Address remoteAddress, EtcdEndpoint endpoint) {
|
||||||
|
assertNotNull(endpoint);
|
||||||
|
assertEquals(SERVICE_NAME, endpoint.getServiceName());
|
||||||
|
assertEquals(remoteAddress.getHost(), endpoint.getHost());
|
||||||
|
assertEquals(remoteAddress.getPort(), endpoint.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* 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 com.google.gson.Gson;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
import mousio.etcd4j.EtcdClient;
|
||||||
|
import mousio.etcd4j.responses.EtcdKeysResponse;
|
||||||
|
import org.apache.skywalking.oap.server.core.cluster.RemoteInstance;
|
||||||
|
import org.apache.skywalking.oap.server.core.remote.client.Address;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Alan Lau
|
||||||
|
*/
|
||||||
|
public class ITClusterEtcdPluginTest {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(ITClusterEtcdPluginTest.class);
|
||||||
|
|
||||||
|
private ClusterModuleEtcdConfig etcdConfig;
|
||||||
|
|
||||||
|
private EtcdClient client;
|
||||||
|
|
||||||
|
private EtcdCoordinator coordinator;
|
||||||
|
|
||||||
|
private Gson gson = new Gson();
|
||||||
|
|
||||||
|
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 static final String SERVICE_NAME = "my-service";
|
||||||
|
|
||||||
|
@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);
|
||||||
|
etcdConfig = new ClusterModuleEtcdConfig();
|
||||||
|
etcdConfig.setServiceName(SERVICE_NAME);
|
||||||
|
client = new EtcdClient(URI.create(baseUrl));
|
||||||
|
coordinator = new EtcdCoordinator(etcdConfig, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void after() throws Exception {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void registerRemote() throws Throwable {
|
||||||
|
registerRemote(remoteAddress);
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void registerSelfRemote() throws Throwable {
|
||||||
|
registerRemote(selfRemoteAddress);
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void registerRemoteUsingInternal() throws Throwable {
|
||||||
|
etcdConfig.setInternalComHost(internalAddress.getHost());
|
||||||
|
etcdConfig.setInternalComPort(internalAddress.getPort());
|
||||||
|
etcdConfig.setServiceName(SERVICE_NAME);
|
||||||
|
registerRemote(internalAddress);
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void queryRemoteNodes() throws Throwable {
|
||||||
|
registerRemote(selfRemoteAddress);
|
||||||
|
List<RemoteInstance> remoteInstances = coordinator.queryRemoteNodes();
|
||||||
|
assertEquals(1, remoteInstances.size());
|
||||||
|
|
||||||
|
RemoteInstance selfInstance = remoteInstances.get(0);
|
||||||
|
velidate(selfRemoteAddress, selfInstance);
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void velidate(Address originArress, RemoteInstance instance) {
|
||||||
|
Address instanceAddress = instance.getAddress();
|
||||||
|
assertEquals(originArress.getHost(), instanceAddress.getHost());
|
||||||
|
assertEquals(originArress.getPort(), instanceAddress.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerRemote(Address address) throws Throwable {
|
||||||
|
coordinator.registerRemote(new RemoteInstance(address));
|
||||||
|
EtcdEndpoint endpoint = afterRegister();
|
||||||
|
verifyRegistration(address, endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private EtcdEndpoint afterRegister() throws Throwable {
|
||||||
|
List<RemoteInstance> list = coordinator.queryRemoteNodes();
|
||||||
|
assertEquals(list.size(), 1L);
|
||||||
|
return buildEndpoint(list.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clear() throws Throwable {
|
||||||
|
EtcdKeysResponse response = client.get(SERVICE_NAME + "/").send().get();
|
||||||
|
List<EtcdKeysResponse.EtcdNode> nodes = response.getNode().getNodes();
|
||||||
|
|
||||||
|
for (EtcdKeysResponse.EtcdNode node : nodes) {
|
||||||
|
client.delete(node.getKey()).send().get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyRegistration(Address remoteAddress, EtcdEndpoint endpoint) {
|
||||||
|
assertNotNull(endpoint);
|
||||||
|
assertEquals(SERVICE_NAME, endpoint.getServiceName());
|
||||||
|
assertEquals(remoteAddress.getHost(), endpoint.getHost());
|
||||||
|
assertEquals(remoteAddress.getPort(), endpoint.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
private EtcdEndpoint buildEndpoint(RemoteInstance instance) {
|
||||||
|
Address address = instance.getAddress();
|
||||||
|
EtcdEndpoint endpoint = new EtcdEndpoint.Builder().host(address.getHost()).port(address.getPort()).serviceName(SERVICE_NAME).build();
|
||||||
|
return endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ 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.
|
||||||
|
~
|
||||||
|
-->
|
||||||
|
|
||||||
|
<Configuration status="info">
|
||||||
|
<Appenders>
|
||||||
|
<Console name="Console" target="SYSTEM_OUT">
|
||||||
|
<PatternLayout charset="UTF-8" pattern="%d - %c -%-4r [%t] %-5p %x - %m%n"/>
|
||||||
|
</Console>
|
||||||
|
</Appenders>
|
||||||
|
<Loggers>
|
||||||
|
<Root level="info">
|
||||||
|
<AppenderRef ref="Console"/>
|
||||||
|
</Root>
|
||||||
|
</Loggers>
|
||||||
|
</Configuration>
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
<module>cluster-kubernetes-plugin</module>
|
<module>cluster-kubernetes-plugin</module>
|
||||||
<module>cluster-consul-plugin</module>
|
<module>cluster-consul-plugin</module>
|
||||||
<module>cluster-nacos-plugin</module>
|
<module>cluster-nacos-plugin</module>
|
||||||
|
<module>cluster-etcd-plugin</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ 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.
|
||||||
|
~
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>server-configuration</artifactId>
|
||||||
|
<groupId>org.apache.skywalking</groupId>
|
||||||
|
<version>6.2.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>configuration-etcd</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.skywalking</groupId>
|
||||||
|
<artifactId>configuration-api</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.skywalking</groupId>
|
||||||
|
<artifactId>library-client</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.skywalking</groupId>
|
||||||
|
<artifactId>cluster-etcd-plugin</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>CI-with-IT</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>io.fabric8</groupId>
|
||||||
|
<artifactId>docker-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<sourceMode>all</sourceMode>
|
||||||
|
<logDate>default</logDate>
|
||||||
|
<verbose>true</verbose>
|
||||||
|
<imagePullPolicy>IfNotPresent</imagePullPolicy>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>start</id>
|
||||||
|
<phase>pre-integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>start</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<images>
|
||||||
|
<image>
|
||||||
|
<name>quayio/coreos-etcd:${etcd.version}</name>
|
||||||
|
<alias>etcd-client-integration-test</alias>
|
||||||
|
<run>
|
||||||
|
<ports>
|
||||||
|
<port>2379:2379</port>
|
||||||
|
</ports>
|
||||||
|
<wait>
|
||||||
|
<time>30000</time>
|
||||||
|
</wait>
|
||||||
|
<entrypoint>
|
||||||
|
<!-- exec form -->
|
||||||
|
<exec>
|
||||||
|
<arg>/usr/local/bin/etcd</arg>
|
||||||
|
<arg>--advertise-client-urls=http://0.0.0.0:2379</arg>
|
||||||
|
<arg>--listen-client-urls=http://0.0.0.0:2379</arg>
|
||||||
|
</exec>
|
||||||
|
</entrypoint>
|
||||||
|
</run>
|
||||||
|
</image>
|
||||||
|
</images>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>remove-it-etcd</id>
|
||||||
|
<phase>post-integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>stop</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
org.apache.skywalking.oap.server.cluster.plugin.etcd.ClusterModuleEtcdProvider
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ 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.
|
||||||
|
~
|
||||||
|
-->
|
||||||
|
|
||||||
|
<Configuration status="info">
|
||||||
|
<Appenders>
|
||||||
|
<Console name="Console" target="SYSTEM_OUT">
|
||||||
|
<PatternLayout charset="UTF-8" pattern="%d - %c -%-4r [%t] %-5p %x - %m%n"/>
|
||||||
|
</Console>
|
||||||
|
</Appenders>
|
||||||
|
<Loggers>
|
||||||
|
<Root level="info">
|
||||||
|
<AppenderRef ref="Console"/>
|
||||||
|
</Root>
|
||||||
|
</Loggers>
|
||||||
|
</Configuration>
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
<module>grpc-configuration-sync</module>
|
<module>grpc-configuration-sync</module>
|
||||||
<module>configuration-apollo</module>
|
<module>configuration-apollo</module>
|
||||||
<module>configuration-nacos</module>
|
<module>configuration-nacos</module>
|
||||||
|
<module>configuration-etcd</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,11 @@
|
||||||
<artifactId>cluster-nacos-plugin</artifactId>
|
<artifactId>cluster-nacos-plugin</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.skywalking</groupId>
|
||||||
|
<artifactId>cluster-etcd-plugin</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- cluster module -->
|
<!-- cluster module -->
|
||||||
|
|
||||||
<!-- receiver module -->
|
<!-- receiver module -->
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,10 @@ cluster:
|
||||||
# nacos:
|
# nacos:
|
||||||
# serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
|
# serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
|
||||||
# hostPort: ${SW_CLUSTER_NACOS_HOST_PORT:localhost:8848}
|
# hostPort: ${SW_CLUSTER_NACOS_HOST_PORT:localhost:8848}
|
||||||
|
# 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}
|
||||||
core:
|
core:
|
||||||
default:
|
default:
|
||||||
# Mixed: Receive agent data, Level 1 aggregate, Level 2 aggregate
|
# Mixed: Receive agent data, Level 1 aggregate, Level 2 aggregate
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,10 @@ cluster:
|
||||||
# nacos:
|
# nacos:
|
||||||
# serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
|
# serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
|
||||||
# hostPort: ${SW_CLUSTER_NACOS_HOST_PORT:localhost:8848}
|
# hostPort: ${SW_CLUSTER_NACOS_HOST_PORT:localhost:8848}
|
||||||
|
# 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}
|
||||||
core:
|
core:
|
||||||
default:
|
default:
|
||||||
# Mixed: Receive agent data, Level 1 aggregate, Level 2 aggregate
|
# Mixed: Receive agent data, Level 1 aggregate, Level 2 aggregate
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue