Feature/oap/cluster plugin (#1440)

* Cluster module implementation finished.
This commit is contained in:
彭勇升 pengys 2018-07-11 14:50:08 +08:00 committed by 吴晟 Wu Sheng
parent e2009b294e
commit dcdfeb1e14
74 changed files with 3371 additions and 13 deletions

View File

@ -16,12 +16,9 @@
*
*/
package org.apache.skywalking.apm.collector.core.util;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
/**
* @author peng-yongsheng

View File

@ -19,8 +19,7 @@
package org.apache.skywalking.apm.collector.storage.base.sql;
import java.text.MessageFormat;
import java.util.List;
import java.util.Set;
import java.util.*;
/**
* @author peng-yongsheng, clevertension
@ -38,7 +37,7 @@ public class SqlBuilder {
public static String buildBatchInsertSql(String tableName, Set<String> columnNames) {
StringBuilder sb = new StringBuilder("insert into ");
sb.append(tableName).append("(");
columnNames.forEach((columnName) -> sb.append(columnName).append(","));
columnNames.forEach(columnName -> sb.append(columnName).append(","));
sb.delete(sb.length() - 1, sb.length());
sb.append(") values(");
for (int i = 0; i < columnNames.size(); i++) {
@ -52,7 +51,7 @@ public class SqlBuilder {
public static String buildBatchUpdateSql(String tableName, Set<String> columnNames, String whereClauseName) {
StringBuilder sb = new StringBuilder("update ");
sb.append(tableName).append(" set ");
columnNames.forEach((columnName) -> sb.append(columnName).append("=?,"));
columnNames.forEach(columnName -> sb.append(columnName).append("=?,"));
sb.delete(sb.length() - 1, sb.length());
sb.append(" where ").append(whereClauseName).append("=?");
return sb.toString();

View File

@ -0,0 +1,43 @@
# Observability Analysis Platform Cluster Management
OAP(Observability Analysis Platform) backend is a distributed system, services need to find each
other. i.e. a web service needs to find query service, level 1 aggregate service need to find
level 2 aggregate service. Cluster management is just a client-side implementation. It must work
together with a distributed coordination service, (i.e. Zookeeper, Consul, Kubernetes.) unless
running in standalone mode.
## Architecture overview
<img src="https://skywalkingtest.github.io/page-resources/6.0.0-alpha/cluster_management.png"/>
### Cluster Management Plugins
By default, OAP backend provides two implementations for cluster management, which are standalone
and zookeeper. When the scale of services, which are under monitoring, is small, you can choose
the standalone mode. Otherwise, you must choose the cluster mode by zookeeper plugin, or you can
implement a new service discovery plugin for your own scene.
### Cluster Management Interface
There are two interfaces defined beforehand in the OAP server core, which are Module register and
module query, all the cluster management plugins must implement those two interfaces.
* Module Register: When any modules need to provide services for others, the module must do register
through this interface.
* Module Query: When any module needs to find other services, it can use this interface to retrieve
the service instance list in the certain order.
### Process Flow Between Client and Cluster Management
The client has two ways to connect the backend, one, use the direct link by a set of backend instance
endpoint list, or you can use naming service, which considers your given list is just the seed nodes
of the whole cluster. The following graph is showing you how naming service works. You need to check
the probe documents to know which way(s) is(are) supported.
```
Client lib Collector1 Collector2 Collector3
(Set collector.servers=Collector2) (Collector 1,2,3 constitute the cluster)
|
+-----------> naming service ---------------------------->|
|
|<------- receive gRPC IP:Port(s) of Collector 1,2,3---<--|
|
|Select a random gRPC service
|For example collector 3
|
|------------------------->Uplink gRPC service----------------------------------->|
```

193
oap-server/pom.xml Normal file
View File

@ -0,0 +1,193 @@
<?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>apm</artifactId>
<groupId>org.apache.skywalking</groupId>
<version>6.0.0-alpha-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>oap-server</artifactId>
<packaging>pom</packaging>
<modules>
<module>server-cluster-plugin</module>
<module>server-library</module>
<module>server-core</module>
<module>server-starter</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4j.version>1.7.25</slf4j.version>
<log4j.version>2.9.0</log4j.version>
<guava.version>19.0</guava.version>
<snakeyaml.version>1.18</snakeyaml.version>
<gson.version>2.8.1</gson.version>
<graphql-java-tools.version>4.3.0</graphql-java-tools.version>
<zookeeper.version>3.4.10</zookeeper.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>${graphql-java-tools.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${joda-time.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>${elasticsearch.client.version}</version>
<exclusions>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
<exclusion>
<artifactId>netty-common</artifactId>
<groupId>io.netty</groupId>
</exclusion>
<exclusion>
<artifactId>netty-transport</artifactId>
<groupId>io.netty</groupId>
</exclusion>
<exclusion>
<artifactId>netty-codec</artifactId>
<groupId>io.netty</groupId>
</exclusion>
<exclusion>
<artifactId>netty-codec-http</artifactId>
<groupId>io.netty</groupId>
</exclusion>
<exclusion>
<artifactId>netty-buffer</artifactId>
<groupId>io.netty</groupId>
</exclusion>
<exclusion>
<artifactId>netty-handler</artifactId>
<groupId>io.netty</groupId>
</exclusion>
<exclusion>
<artifactId>netty-resolver</artifactId>
<groupId>io.netty</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper.version}</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>${snakeyaml.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
</project>

View File

@ -0,0 +1,40 @@
<?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.0.0-alpha-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cluster-standalone-plugin</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>core-cluster</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,61 @@
/*
* 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.standalone;
import org.apache.skywalking.oap.server.core.cluster.*;
import org.apache.skywalking.oap.server.library.module.*;
import org.slf4j.*;
/**
* @author peng-yongsheng
*/
public class ClusterModuleStandaloneProvider extends ModuleProvider {
private static final Logger logger = LoggerFactory.getLogger(ClusterModuleStandaloneProvider.class);
private final StandaloneServiceManager serviceManager;
public ClusterModuleStandaloneProvider() {
super();
this.serviceManager = new StandaloneServiceManager();
}
@Override public String name() {
return "standalone";
}
@Override public Class module() {
return ClusterModule.class;
}
@Override public ModuleConfig createConfigBeanIfAbsent() {
return null;
}
@Override public void prepare() throws ServiceNotProvidedException {
this.registerServiceImplementation(ModuleRegister.class, new StandaloneModuleRegister(serviceManager));
this.registerServiceImplementation(ModuleQuery.class, new StandaloneModuleQuery(serviceManager));
}
@Override public void start() throws ModuleStartException {
}
@Override public void notifyAfterCompleted() {
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.standalone;
import java.util.*;
import org.apache.skywalking.oap.server.core.cluster.*;
/**
* @author peng-yongsheng
*/
public class StandaloneModuleQuery implements ModuleQuery {
private final StandaloneServiceManager serviceManager;
StandaloneModuleQuery(StandaloneServiceManager serviceManager) {
this.serviceManager = serviceManager;
}
@Override
public List<InstanceDetails> query(String moduleName, String providerName) {
List<InstanceDetails> instanceDetails = new ArrayList<>(1);
instanceDetails.add(serviceManager.get(moduleName, providerName));
return instanceDetails;
}
}

View File

@ -0,0 +1,38 @@
/*
* 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.standalone;
import org.apache.skywalking.oap.server.core.cluster.*;
/**
* @author peng-yongsheng
*/
public class StandaloneModuleRegister implements ModuleRegister {
private final StandaloneServiceManager serviceManager;
StandaloneModuleRegister(StandaloneServiceManager serviceManager) {
this.serviceManager = serviceManager;
}
@Override public void register(String moduleName, String providerName,
InstanceDetails instanceDetails) {
serviceManager.put(moduleName, providerName, instanceDetails);
}
}

View File

@ -0,0 +1,32 @@
/*
* 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.standalone;
import org.apache.skywalking.oap.server.core.cluster.*;
/**
* @author peng-yongsheng
*/
public class StandaloneRegister implements ModuleRegister {
@Override public void register(String moduleName, String providerName,
InstanceDetails instanceDetails) throws ServiceRegisterException {
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.standalone;
import java.util.*;
import org.apache.skywalking.oap.server.core.cluster.InstanceDetails;
/**
* @author peng-yongsheng
*/
public class StandaloneServiceManager {
private final Map<String, InstanceDetails> instanceDetailsMap;
public StandaloneServiceManager() {
this.instanceDetailsMap = new HashMap<>();
}
public void put(String moduleName, String providerName, InstanceDetails instanceDetails) {
instanceDetailsMap.put(moduleName + "/" + providerName, instanceDetails);
}
public InstanceDetails get(String moduleName, String providerName) {
return instanceDetailsMap.get(moduleName + "/" + providerName);
}
}

View File

@ -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.standalone.ClusterModuleStandaloneProvider

View File

@ -0,0 +1,77 @@
<?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>
<groupId>org.apache.skywalking</groupId>
<artifactId>server-cluster-plugin</artifactId>
<version>6.0.0-alpha-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cluster-zookeeper-plugin</artifactId>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<curator.version>4.0.1</curator.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>core-cluster</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-x-discovery</artifactId>
<version>${curator.version}</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-test</artifactId>
<version>2.12.0</version>
<!--<version>${curator.version}</version>-->
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,55 @@
/*
* 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.zookeeper;
import org.apache.skywalking.oap.server.library.module.ModuleConfig;
import org.apache.skywalking.oap.server.library.util.StringUtils;
/**
* @author peng-yongsheng
*/
class ClusterModuleZookeeperConfig extends ModuleConfig {
private String hostPort;
private int baseSleepTimeMs;
private int maxRetries;
public String getHostPort() {
return StringUtils.isNotEmpty(hostPort) ? hostPort : "localhost:2181";
}
public void setHostPort(String hostPort) {
this.hostPort = hostPort;
}
public int getBaseSleepTimeMs() {
return baseSleepTimeMs > 0 ? baseSleepTimeMs : 1000;
}
public void setBaseSleepTimeMs(int baseSleepTimeMs) {
this.baseSleepTimeMs = baseSleepTimeMs;
}
public int getMaxRetries() {
return maxRetries > 0 ? maxRetries : 3;
}
public void setMaxRetries(int maxRetries) {
this.maxRetries = maxRetries;
}
}

View File

@ -0,0 +1,86 @@
/*
* 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.zookeeper;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.*;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.x.discovery.*;
import org.apache.skywalking.oap.server.core.cluster.*;
import org.apache.skywalking.oap.server.library.module.*;
import org.slf4j.*;
/**
* @author peng-yongsheng
*/
public class ClusterModuleZookeeperProvider extends ModuleProvider {
private static final Logger logger = LoggerFactory.getLogger(ClusterModuleZookeeperProvider.class);
private static final String BASE_PATH = "/skywalking";
private final ServiceCacheManager cacheManager;
private final ClusterModuleZookeeperConfig config;
private CuratorFramework client;
private ServiceDiscovery<InstanceDetails> serviceDiscovery;
public ClusterModuleZookeeperProvider() {
super();
this.config = new ClusterModuleZookeeperConfig();
this.cacheManager = new ServiceCacheManager();
}
@Override public String name() {
return "zookeeper";
}
@Override public Class module() {
return ClusterModule.class;
}
@Override public ModuleConfig createConfigBeanIfAbsent() {
return config;
}
@Override public void prepare() throws ServiceNotProvidedException {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(config.getBaseSleepTimeMs(), config.getMaxRetries());
client = CuratorFrameworkFactory.newClient(config.getHostPort(), retryPolicy);
serviceDiscovery = ServiceDiscoveryBuilder.builder(InstanceDetails.class).client(client)
.basePath(BASE_PATH)
.watchInstances(true)
.serializer(new SWInstanceSerializer()).build();
this.registerServiceImplementation(ModuleRegister.class, new ZookeeperModuleRegister(serviceDiscovery, cacheManager));
this.registerServiceImplementation(ModuleQuery.class, new ZookeeperModuleQuery(cacheManager));
}
@Override public void start() throws ModuleStartException {
try {
client.start();
client.blockUntilConnected();
serviceDiscovery.start();
} catch (Exception e) {
throw new ModuleStartException(e.getMessage(), e);
}
}
@Override public void notifyAfterCompleted() {
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.zookeeper;
/**
* @author peng-yongsheng
*/
public class NodeNameBuilder {
public static String build(String moduleName, String providerName) {
return moduleName + "/" + providerName;
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.zookeeper;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.curator.x.discovery.ServiceInstance;
import org.apache.curator.x.discovery.details.InstanceSerializer;
import org.apache.skywalking.oap.server.core.cluster.InstanceDetails;
/**
* @author peng-yongsheng
*/
public class SWInstanceSerializer implements InstanceSerializer<InstanceDetails> {
private final Gson gson = new Gson();
@Override public byte[] serialize(ServiceInstance<InstanceDetails> instance) throws Exception {
return gson.toJson(instance).getBytes();
}
@Override public ServiceInstance<InstanceDetails> deserialize(byte[] bytes) throws Exception {
return gson.fromJson(new String(bytes), new TypeToken<ServiceInstance<InstanceDetails>>() {
}.getType());
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.zookeeper;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.curator.x.discovery.ServiceCache;
import org.apache.skywalking.oap.server.core.cluster.InstanceDetails;
/**
* @author peng-yongsheng
*/
public class ServiceCacheManager {
private final Map<String, ServiceCache<InstanceDetails>> serviceCacheMap;
public ServiceCacheManager() {
this.serviceCacheMap = new ConcurrentHashMap<>();
}
public void put(String name, ServiceCache<InstanceDetails> cache) {
serviceCacheMap.put(name, cache);
}
public ServiceCache<InstanceDetails> get(String name) {
return serviceCacheMap.get(name);
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.zookeeper;
import java.util.*;
import org.apache.curator.x.discovery.ServiceInstance;
import org.apache.skywalking.oap.server.core.cluster.*;
/**
* @author peng-yongsheng
*/
public class ZookeeperModuleQuery implements ModuleQuery {
private final ServiceCacheManager cacheManager;
ZookeeperModuleQuery(ServiceCacheManager cacheManager) {
this.cacheManager = cacheManager;
}
@Override
public List<InstanceDetails> query(String moduleName, String providerName) throws ServiceRegisterException {
List<ServiceInstance<InstanceDetails>> serviceInstances = cacheManager.get(NodeNameBuilder.build(moduleName, providerName)).getInstances();
List<InstanceDetails> instanceDetails = new ArrayList<>(serviceInstances.size());
serviceInstances.forEach(serviceInstance -> instanceDetails.add(serviceInstance.getPayload()));
return instanceDetails;
}
}

View File

@ -0,0 +1,66 @@
/*
* 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.zookeeper;
import java.util.UUID;
import org.apache.curator.x.discovery.*;
import org.apache.skywalking.oap.server.core.cluster.*;
/**
* @author peng-yongsheng
*/
public class ZookeeperModuleRegister implements ModuleRegister {
private final ServiceDiscovery<InstanceDetails> serviceDiscovery;
private final ServiceCacheManager cacheManager;
ZookeeperModuleRegister(ServiceDiscovery<InstanceDetails> serviceDiscovery,
ServiceCacheManager cacheManager) {
this.serviceDiscovery = serviceDiscovery;
this.cacheManager = cacheManager;
}
@Override public synchronized void register(String moduleName, String providerName,
InstanceDetails instanceDetails) throws ServiceRegisterException {
try {
String name = NodeNameBuilder.build(moduleName, providerName);
ServiceInstance<InstanceDetails> thisInstance = ServiceInstance.<InstanceDetails>builder()
.name(NodeNameBuilder.build(moduleName, providerName))
.id(UUID.randomUUID().toString())
.address(instanceDetails.getHost())
.port(instanceDetails.getPort())
// .uriSpec(new UriSpec(StringUtils.isEmpty(instanceDetails.getContextPath()) ? StringUtils.EMPTY_STRING : instanceDetails.getContextPath()))
.payload(instanceDetails)
.build();
serviceDiscovery.registerService(thisInstance);
ServiceCache<InstanceDetails> serviceCache = serviceDiscovery.serviceCacheBuilder()
.name(name)
.build();
serviceCache.start();
cacheManager.put(name, serviceCache);
} catch (Exception e) {
e.printStackTrace();
throw new ServiceRegisterException(e.getMessage());
}
}
}

View File

@ -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.zookeeper.ClusterModuleZookeeperProvider

View File

@ -0,0 +1,71 @@
/*
* 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.zookeeper;
import java.io.IOException;
import java.util.List;
import org.apache.curator.test.TestingServer;
import org.apache.skywalking.oap.server.core.cluster.*;
import org.apache.skywalking.oap.server.library.module.*;
import org.junit.*;
/**
* @author peng-yongsheng
*/
public class ClusterModuleZookeeperProviderTestCase {
private TestingServer server;
@Before
public void before() throws Exception {
server = new TestingServer(12181, true);
server.start();
}
@Test
public void testStart() throws ServiceNotProvidedException, ModuleStartException, ServiceRegisterException {
ClusterModuleZookeeperProvider provider = new ClusterModuleZookeeperProvider();
ClusterModuleZookeeperConfig moduleConfig = (ClusterModuleZookeeperConfig)provider.createConfigBeanIfAbsent();
moduleConfig.setHostPort(server.getConnectString());
moduleConfig.setBaseSleepTimeMs(3000);
moduleConfig.setMaxRetries(4);
provider.prepare();
provider.start();
ModuleRegister moduleRegister = provider.getService(ModuleRegister.class);
ModuleQuery moduleQuery = provider.getService(ModuleQuery.class);
InstanceDetails instanceDetails = new InstanceDetails();
instanceDetails.setHost("ProviderAHost");
instanceDetails.setPort(1000);
moduleRegister.register("ModuleA", "ProviderA", instanceDetails);
List<InstanceDetails> detailsList = moduleQuery.query("ModuleA", "ProviderA");
Assert.assertEquals(1, detailsList.size());
Assert.assertEquals("ProviderAHost", detailsList.get(0).getHost());
Assert.assertEquals(1000, detailsList.get(0).getPort());
}
@After
public void after() throws IOException {
server.stop();
}
}

View File

@ -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>

View File

@ -0,0 +1,49 @@
<?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>oap-server</artifactId>
<groupId>org.apache.skywalking</groupId>
<version>6.0.0-alpha-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>server-cluster-plugin</artifactId>
<packaging>pom</packaging>
<modules>
<module>cluster-zookeeper-plugin</module>
<module>cluster-standalone-plugin</module>
</modules>
<dependencies>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>library-module</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>library-util</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,33 @@
<?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>
<groupId>org.apache.skywalking</groupId>
<artifactId>server-core</artifactId>
<version>6.0.0-alpha-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>core-cluster</artifactId>
<packaging>jar</packaging>
</project>

View File

@ -0,0 +1,37 @@
/*
* 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.core.cluster;
import org.apache.skywalking.oap.server.library.module.ModuleDefine;
/**
* @author peng-yongsheng
*/
public class ClusterModule extends ModuleDefine {
public static final String NAME = "cluster";
@Override public String name() {
return NAME;
}
@Override public Class[] services() {
return new Class[] {ModuleRegister.class, ModuleQuery.class};
}
}

View File

@ -0,0 +1,53 @@
/*
* 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.core.cluster;
/**
* @author peng-yongsheng
*/
public class InstanceDetails {
private String host;
private int port;
private String contextPath;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getContextPath() {
return contextPath;
}
public void setContextPath(String contextPath) {
this.contextPath = contextPath;
}
}

View File

@ -0,0 +1,30 @@
/*
* 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.core.cluster;
import java.util.List;
import org.apache.skywalking.oap.server.library.module.Service;
/**
* @author peng-yongsheng
*/
public interface ModuleQuery extends Service {
List<InstanceDetails> query(String moduleName, String providerName) throws ServiceRegisterException;
}

View File

@ -0,0 +1,30 @@
/*
* 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.core.cluster;
import org.apache.skywalking.oap.server.library.module.Service;
/**
* @author peng-yongsheng
*/
public interface ModuleRegister extends Service {
void register(String moduleName, String providerName,
InstanceDetails instanceDetails) throws ServiceRegisterException;
}

View File

@ -0,0 +1,29 @@
/*
* 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.core.cluster;
/**
* @author peng-yongsheng
*/
public class ServiceRegisterException extends Exception {
public ServiceRegisterException(String message) {
super(message);
}
}

View File

@ -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.core.cluster.ClusterModule

View File

@ -0,0 +1,48 @@
<?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>oap-server</artifactId>
<groupId>org.apache.skywalking</groupId>
<version>6.0.0-alpha-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>server-core</artifactId>
<packaging>pom</packaging>
<modules>
<module>core-cluster</module>
</modules>
<dependencies>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>library-module</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>library-util</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,32 @@
<?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-library</artifactId>
<groupId>org.apache.skywalking</groupId>
<version>6.0.0-alpha-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>library-module</artifactId>
<packaging>jar</packaging>
</project>

View File

@ -0,0 +1,92 @@
/*
* 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.library.module;
import java.util.*;
/**
* Modularization configurations. The {@link ModuleManager} is going to start, lookup, start modules based on this.
*
* @author wu-sheng, peng-yongsheng
*/
public class ApplicationConfiguration {
private final Map<String, ModuleConfiguration> modules = new HashMap<>();
public String[] moduleList() {
return modules.keySet().toArray(new String[0]);
}
public ModuleConfiguration addModule(String moduleName) {
ModuleConfiguration newModule = new ModuleConfiguration();
modules.put(moduleName, newModule);
return newModule;
}
public boolean has(String moduleName) {
return modules.containsKey(moduleName);
}
public ModuleConfiguration getModuleConfiguration(String name) {
return modules.get(name);
}
/**
* The configurations about a certain module.
*/
public class ModuleConfiguration {
private final Map<String, ProviderConfiguration> providers = new HashMap<>();
private ModuleConfiguration() {
}
public Properties getProviderConfiguration(String name) {
return providers.get(name).getProperties();
}
public boolean has(String name) {
return providers.containsKey(name);
}
public String[] providerList() {
return providers.keySet().toArray(new String[0]);
}
public ModuleConfiguration addProviderConfiguration(String name, Properties properties) {
ProviderConfiguration newProvider = new ProviderConfiguration(properties);
providers.put(name, newProvider);
return this;
}
}
/**
* The configuration about a certain provider of a module.
*/
public class ProviderConfiguration {
private Properties properties;
ProviderConfiguration(Properties properties) {
this.properties = properties;
}
private Properties getProperties() {
return properties;
}
}
}

View File

@ -0,0 +1,25 @@
/*
* 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.library.module;
public class DuplicateProviderException extends Exception {
public DuplicateProviderException(String message) {
super(message);
}
}

View File

@ -0,0 +1,25 @@
/*
* 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.library.module;
/**
* @author peng-yongsheng
*/
public abstract class ModuleConfig {
}

View File

@ -0,0 +1,33 @@
/*
* 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.library.module;
/**
* @author peng-yongsheng
*/
public class ModuleConfigException extends Exception {
public ModuleConfigException(String message) {
super(message);
}
public ModuleConfigException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,133 @@
/*
* 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.library.module;
import java.lang.reflect.Field;
import java.util.*;
import org.slf4j.*;
/**
* A module definition.
*
* @author wu-sheng, peng-yongsheng
*/
public abstract class ModuleDefine {
private static final Logger logger = LoggerFactory.getLogger(ModuleDefine.class);
private ModuleProvider moduleProvider;
/**
* @return the module name
*/
public abstract String name();
/**
* @return the {@link Service} provided by this module.
*/
public abstract Class[] services();
/**
* Run the prepare stage for the module, including finding all potential providers, and asking them to prepare.
*
* @param moduleManager of this module
* @param configuration of this module
* @throws ProviderNotFoundException when even don't find a single one providers.
*/
void prepare(ModuleManager moduleManager,
ApplicationConfiguration.ModuleConfiguration configuration) throws ProviderNotFoundException, ServiceNotProvidedException, ModuleConfigException {
ServiceLoader<ModuleProvider> moduleProviderLoader = ServiceLoader.load(ModuleProvider.class);
if (configuration.providerList().length != 1) {
throw new ModuleConfigException("Just a single provider configuration allowed to open in one module.");
}
boolean providerExist = false;
for (ModuleProvider provider : moduleProviderLoader) {
if (!configuration.has(provider.name())) {
continue;
}
providerExist = true;
if (provider.module().equals(getClass())) {
try {
moduleProvider = provider.getClass().newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new ProviderNotFoundException(e);
}
moduleProvider.setManager(moduleManager);
moduleProvider.setModule(this);
}
}
if (!providerExist) {
throw new ProviderNotFoundException(this.name() + " module no provider exists.");
}
logger.info("Prepare the {} provider in {} module.", moduleProvider.name(), this.name());
try {
copyProperties(moduleProvider.createConfigBeanIfAbsent(), configuration.getProviderConfiguration(moduleProvider.name()), this.name(), moduleProvider.name());
} catch (IllegalAccessException e) {
throw new ModuleConfigException(this.name() + " module config transport to config bean failure.", e);
}
moduleProvider.prepare();
}
private void copyProperties(ModuleConfig dest, Properties src, String moduleName,
String providerName) throws IllegalAccessException {
Enumeration<?> propertyNames = src.propertyNames();
while (propertyNames.hasMoreElements()) {
String propertyName = (String)propertyNames.nextElement();
Class<? extends ModuleConfig> destClass = dest.getClass();
try {
Field field = getDeclaredField(destClass, propertyName);
field.setAccessible(true);
field.set(dest, src.get(propertyName));
} catch (NoSuchFieldException e) {
logger.warn(propertyName + " setting is not supported in " + providerName + " provider of " + moduleName + " module");
}
}
}
private Field getDeclaredField(Class<?> destClass, String fieldName) throws NoSuchFieldException {
if (destClass != null) {
Field[] fields = destClass.getDeclaredFields();
for (Field field : fields) {
if (field.getName().equals(fieldName)) {
return field;
}
}
return getDeclaredField(destClass.getSuperclass(), fieldName);
}
throw new NoSuchFieldException();
}
final ModuleProvider provider() {
return moduleProvider;
}
public final <T extends Service> T getService(Class<T> serviceType) throws ServiceNotProvidedRuntimeException {
try {
return provider().getService(serviceType);
} catch (ServiceNotProvidedException e) {
throw new ServiceNotProvidedRuntimeException(e.getMessage());
}
}
}

View File

@ -0,0 +1,86 @@
/*
* 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.library.module;
import java.util.*;
/**
* The <code>ModuleManager</code> takes charge of all {@link ModuleDefine}s in collector.
*
* @author wu-sheng, peng-yongsheng
*/
public class ModuleManager {
private boolean isInPrepareStage = true;
private final Map<String, ModuleDefine> loadedModules = new HashMap<>();
/**
* Init the given modules
*/
public void init(
ApplicationConfiguration applicationConfiguration) throws ModuleNotFoundException, ProviderNotFoundException, ServiceNotProvidedException, ModuleConfigException, DuplicateProviderException, ModuleStartException {
String[] moduleNames = applicationConfiguration.moduleList();
ServiceLoader<ModuleDefine> moduleServiceLoader = ServiceLoader.load(ModuleDefine.class);
List<String> moduleList = new LinkedList<>(Arrays.asList(moduleNames));
for (ModuleDefine module : moduleServiceLoader) {
for (String moduleName : moduleNames) {
if (moduleName.equals(module.name())) {
ModuleDefine newInstance;
try {
newInstance = module.getClass().newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new ModuleNotFoundException(e);
}
newInstance.prepare(this, applicationConfiguration.getModuleConfiguration(moduleName));
loadedModules.put(moduleName, newInstance);
moduleList.remove(moduleName);
}
}
}
// Finish prepare stage
isInPrepareStage = false;
if (moduleList.size() > 0) {
throw new ModuleNotFoundException(moduleList.toString() + " missing.");
}
for (ModuleDefine module : loadedModules.values()) {
module.provider().start();
module.provider().notifyAfterCompleted();
}
}
public boolean has(String moduleName) {
return loadedModules.get(moduleName) != null;
}
public ModuleDefine find(String moduleName) throws ModuleNotFoundRuntimeException {
assertPreparedStage();
ModuleDefine module = loadedModules.get(moduleName);
if (module != null)
return module;
throw new ModuleNotFoundRuntimeException(moduleName + " missing.");
}
private void assertPreparedStage() {
if (isInPrepareStage) {
throw new AssertionError("Still in preparing stage.");
}
}
}

View File

@ -0,0 +1,30 @@
/*
* 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.library.module;
public class ModuleNotFoundException extends Exception {
public ModuleNotFoundException(Throwable cause) {
super(cause);
}
public ModuleNotFoundException(String message) {
super(message);
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.library.module;
/**
* @author peng-yongsheng
*/
public class ModuleNotFoundRuntimeException extends RuntimeException {
public ModuleNotFoundRuntimeException(String message) {
super(message);
}
}

View File

@ -0,0 +1,131 @@
/*
* 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.library.module;
import java.util.*;
/**
* The <code>ModuleProvider</code> is an implementation of a {@link ModuleDefine}.
*
* And each module can have one or more implementation, which depends on `application.yml`
*
* @author wu-sheng, peng-yongsheng
*/
public abstract class ModuleProvider {
private ModuleManager manager;
private ModuleDefine module;
private Map<Class<? extends Service>, Service> services = new HashMap<>();
public ModuleProvider() {
}
void setManager(ModuleManager manager) {
this.manager = manager;
}
void setModule(ModuleDefine module) {
this.module = module;
}
protected final ModuleManager getManager() {
return manager;
}
/**
* @return the name of this provider.
*/
public abstract String name();
/**
* @return the module name
*/
public abstract Class module();
/**
* @return ModuleConfig
*/
public abstract ModuleConfig createConfigBeanIfAbsent();
/**
* In prepare stage, the module should initialize things which are irrelative other modules.
*/
public abstract void prepare() throws ServiceNotProvidedException;
/**
* In start stage, the module has been ready for interop.
*/
public abstract void start() throws ServiceNotProvidedException, ModuleStartException;
/**
* This callback executes after all modules start up successfully.
*/
public abstract void notifyAfterCompleted() throws ServiceNotProvidedException;
/**
* Register a implementation for the service of this module provider.
*/
protected final void registerServiceImplementation(Class<? extends Service> serviceType,
Service service) throws ServiceNotProvidedException {
if (serviceType.isInstance(service)) {
this.services.put(serviceType, service);
} else {
throw new ServiceNotProvidedException(serviceType + " is not implemented by " + service);
}
}
/**
* Make sure all required services have been implemented.
*
* @param requiredServices must be implemented by the module.
* @throws ServiceNotProvidedException when exist unimplemented service.
*/
void requiredCheck(Class<? extends Service>[] requiredServices) throws ServiceNotProvidedException {
if (requiredServices == null)
return;
for (Class<? extends Service> service : requiredServices) {
if (!services.containsKey(service)) {
throw new ServiceNotProvidedException("Service:" + service.getName() + " not provided");
}
}
if (requiredServices.length != services.size()) {
throw new ServiceNotProvidedException("The " + this.name() + " provider in " + module.name() + " module provide more service implementations than ModuleDefine requirements.");
}
}
@SuppressWarnings("unchecked")
public <T extends Service> T getService(
Class<T> serviceType) throws ServiceNotProvidedException {
Service serviceImpl = services.get(serviceType);
if (serviceImpl != null) {
return (T)serviceImpl;
}
throw new ServiceNotProvidedException("Service " + serviceType.getName() + " should not be provided, based on module define.");
}
ModuleDefine getModule() {
return module;
}
String getModuleName() {
return module.name();
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.library.module;
/**
* @author peng-yongsheng
*/
public class ModuleStartException extends Exception {
public ModuleStartException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.library.module;
public class ProviderNotFoundException extends Exception {
public ProviderNotFoundException(String message) {
super(message);
}
public ProviderNotFoundException(Throwable e) {
super(e);
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.library.module;
/**
* The <code>Service</code> implementation is a service provided by its own modules.
*
* And every {@link ModuleProvider} must provide all the given services of the {@link ModuleDefine}.
*
* @author wu-sheng
*/
public interface Service {
}

View File

@ -0,0 +1,25 @@
/*
* 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.library.module;
public class ServiceNotProvidedException extends Exception {
public ServiceNotProvidedException(String message) {
super(message);
}
}

View File

@ -0,0 +1,25 @@
/*
* 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.library.module;
public class ServiceNotProvidedRuntimeException extends RuntimeException {
public ServiceNotProvidedRuntimeException(String message) {
super(message);
}
}

View File

@ -0,0 +1,56 @@
/*
* 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.library.module;
import java.util.Properties;
import org.junit.*;
/**
* @author peng-yongsheng
*/
public class ApplicationConfigurationTestCase {
@Test
public void test() {
ApplicationConfiguration configuration = new ApplicationConfiguration();
Properties providerAConfig = new Properties();
providerAConfig.setProperty("A-key1", "A-value1");
providerAConfig.setProperty("A-key2", "A-value2");
Properties providerBConfig = new Properties();
providerBConfig.setProperty("B-key1", "B-value1");
providerBConfig.setProperty("B-key2", "B-value2");
final String module = "Module";
final String providerA = "ProviderA";
final String providerB = "ProviderB";
configuration.addModule(module)
.addProviderConfiguration(providerA, providerAConfig)
.addProviderConfiguration(providerB, providerBConfig);
Assert.assertArrayEquals(new String[] {module}, configuration.moduleList());
Assert.assertTrue(configuration.has(module));
Assert.assertFalse(configuration.has("ModuleB"));
Assert.assertTrue(configuration.getModuleConfiguration(module).has(providerA));
Assert.assertFalse(configuration.getModuleConfiguration(module).has("ProviderC"));
Assert.assertEquals("B-value1", configuration.getModuleConfiguration(module).getProviderConfiguration(providerB).getProperty("B-key1"));
Assert.assertEquals(providerAConfig, configuration.getModuleConfiguration(module).getProviderConfiguration(providerA));
}
}

View File

@ -0,0 +1,43 @@
/*
* 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.library.module;
/**
* @author wu-sheng, peng-yongsheng
*/
public class BaseModuleA extends ModuleDefine {
static final String NAME = "BaseModuleA";
@Override public String name() {
return NAME;
}
@Override public Class[] services() {
return new Class[] {ServiceABusiness1.class, ServiceABusiness2.class};
}
public interface ServiceABusiness1 extends Service {
void print();
}
public interface ServiceABusiness2 extends Service {
}
}

View File

@ -0,0 +1,43 @@
/*
* 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.library.module;
/**
* @author wu-sheng
*/
public class BaseModuleB extends ModuleDefine {
static final String NAME = "BaseModuleB";
@Override public String name() {
return NAME;
}
@Override public Class[] services() {
return new Class[] {BaseModuleB.ServiceBBusiness1.class, BaseModuleB.ServiceBBusiness2.class};
}
public interface ServiceBBusiness1 extends Service {
}
public interface ServiceBBusiness2 extends Service {
}
}

View File

@ -0,0 +1,28 @@
/*
* 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.library.module;
/**
* @author wu-sheng
*/
public class ModuleABusiness1Impl implements BaseModuleA.ServiceABusiness1 {
@Override public void print() {
}
}

View File

@ -0,0 +1,26 @@
/*
* 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.library.module;
/**
* @author wu-sheng
*/
public class ModuleABusiness2Impl implements BaseModuleA.ServiceABusiness2 {
}

View File

@ -0,0 +1,63 @@
/*
* 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.library.module;
/**
* @author wu-sheng, peng-yongsheng
*/
public class ModuleAProvider extends ModuleProvider {
static final String NAME = "ModuleAProvider";
private ModuleConfig config;
@Override public String name() {
return NAME;
}
@Override public ModuleConfig createConfigBeanIfAbsent() {
if (config == null) {
config = new Config();
}
return config;
}
@Override public Class<? extends ModuleDefine> module() {
return BaseModuleA.class;
}
@Override public void prepare() throws ServiceNotProvidedException {
this.registerServiceImplementation(BaseModuleA.ServiceABusiness1.class, new ModuleABusiness1Impl());
this.registerServiceImplementation(BaseModuleA.ServiceABusiness2.class, new ModuleABusiness2Impl());
}
@Override public void start() {
}
@Override public void notifyAfterCompleted() {
}
public class Config extends ModuleConfig {
private String host;
public String getHost() {
return host;
}
}
}

View File

@ -0,0 +1,25 @@
/*
* 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.library.module;
/**
* @author wu-sheng
*/
public class ModuleBBusiness1Impl implements BaseModuleB.ServiceBBusiness1 {
}

View File

@ -0,0 +1,25 @@
/*
* 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.library.module;
/**
* @author wu-sheng
*/
public class ModuleBBusiness2Impl implements BaseModuleB.ServiceBBusiness2 {
}

View File

@ -0,0 +1,53 @@
/*
* 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.library.module;
/**
* @author wu-sheng, peng-yongsheng
*/
public class ModuleBProvider extends ModuleProvider {
static final String NAME = "ModuleBProvider";
@Override public String name() {
return NAME;
}
@Override public ModuleConfig createConfigBeanIfAbsent() {
return null;
}
@Override public Class<? extends ModuleDefine> module() {
return BaseModuleB.class;
}
@Override public void prepare() throws ServiceNotProvidedException {
this.registerServiceImplementation(BaseModuleB.ServiceBBusiness1.class, new ModuleBBusiness1Impl());
this.registerServiceImplementation(BaseModuleB.ServiceBBusiness2.class, new ModuleBBusiness2Impl());
}
@Override public void start() {
}
@Override public void notifyAfterCompleted() {
}
class Config {
}
}

View File

@ -0,0 +1,102 @@
/*
* 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.library.module;
import java.util.Properties;
import org.junit.*;
/**
* @author peng-yongsheng
*/
public class ModuleManagerTestCase {
private ApplicationConfiguration configuration;
@Before
public void init() {
Properties providerAConfig = new Properties();
providerAConfig.setProperty("host", "oap");
providerAConfig.setProperty("A-key1", "A-value1");
providerAConfig.setProperty("A-key2", "A-value2");
configuration = new ApplicationConfiguration();
configuration.addModule(TestModule.NAME).addProviderConfiguration(TestModuleProvider.NAME, new Properties());
configuration.addModule(BaseModuleA.NAME).addProviderConfiguration(ModuleAProvider.NAME, providerAConfig);
configuration.addModule(BaseModuleB.NAME).addProviderConfiguration(ModuleBProvider.NAME, new Properties());
}
@Test
public void testHas() throws ModuleNotFoundException, ModuleConfigException, ServiceNotProvidedException, ProviderNotFoundException, ModuleStartException, DuplicateProviderException {
ModuleManager manager = new ModuleManager();
manager.init(configuration);
Assert.assertTrue(manager.has(TestModule.NAME));
Assert.assertTrue(manager.has(BaseModuleA.NAME));
Assert.assertTrue(manager.has(BaseModuleB.NAME));
Assert.assertFalse(manager.has("Undefined"));
}
@Test
public void testFind() throws ModuleNotFoundException, ModuleConfigException, ServiceNotProvidedException, ProviderNotFoundException, ModuleStartException, DuplicateProviderException {
ModuleManager manager = new ModuleManager();
manager.init(configuration);
try {
manager.find("Undefined");
} catch (ModuleNotFoundRuntimeException e) {
Assert.assertEquals("Undefined missing.", e.getMessage());
}
}
@Test
public void testInit() throws ServiceNotProvidedException, DuplicateProviderException, ModuleConfigException, ModuleNotFoundException, ProviderNotFoundException, ModuleStartException {
ModuleManager manager = new ModuleManager();
manager.init(configuration);
BaseModuleA.ServiceABusiness1 serviceABusiness1 = manager.find(BaseModuleA.NAME).provider().getService(BaseModuleA.ServiceABusiness1.class);
Assert.assertNotNull(serviceABusiness1);
ModuleAProvider.Config config = (ModuleAProvider.Config)manager.find(BaseModuleA.NAME).provider().createConfigBeanIfAbsent();
Assert.assertEquals("oap", config.getHost());
}
@Test
public void testAssertPreparedStage() {
ModuleManager manager = new ModuleManager();
try {
manager.find("Undefined");
} catch (AssertionError e) {
Assert.assertEquals("Still in preparing stage.", e.getMessage());
}
}
@Test
public void testEmptyConfig() throws ModuleConfigException, ServiceNotProvidedException, ProviderNotFoundException, ModuleStartException, DuplicateProviderException {
configuration.addModule("Undefined").addProviderConfiguration("Undefined", new Properties());
ModuleManager manager = new ModuleManager();
try {
manager.init(configuration);
} catch (ModuleNotFoundException e) {
Assert.assertEquals("[Undefined] missing.", e.getMessage());
}
}
}

View File

@ -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.library.module;
/**
* @author wu-sheng, peng-yongsheng
*/
public class TestModule extends ModuleDefine {
static final String NAME = "TestModule";
@Override public String name() {
return NAME;
}
@Override public Class[] services() {
return new Class[0];
}
}

View File

@ -0,0 +1,51 @@
/*
* 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.library.module;
/**
* @author wu-sheng
*/
public class TestModuleProvider extends ModuleProvider {
static final String NAME = "TestModuleProvider";
@Override public String name() {
return NAME;
}
@Override public Class<? extends ModuleDefine> module() {
return TestModule.class;
}
@Override public ModuleConfig createConfigBeanIfAbsent() {
return null;
}
@Override public void prepare() {
}
@Override public void start() {
}
@Override public void notifyAfterCompleted() {
}
class Config {
}
}

View File

@ -0,0 +1,21 @@
#
# 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.library.module.TestModule
org.apache.skywalking.oap.server.library.module.BaseModuleA
org.apache.skywalking.oap.server.library.module.BaseModuleB

View File

@ -0,0 +1,21 @@
#
# 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.library.module.TestModuleProvider
org.apache.skywalking.oap.server.library.module.ModuleAProvider
org.apache.skywalking.oap.server.library.module.ModuleBProvider

View File

@ -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>

View File

@ -0,0 +1,32 @@
<?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-library</artifactId>
<groupId>org.apache.skywalking</groupId>
<version>6.0.0-alpha-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>library-util</artifactId>
<packaging>jar</packaging>
</project>

View File

@ -0,0 +1,56 @@
/*
* 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.library.util;
import java.util.*;
/**
* @author peng-yongsheng
*/
public class CollectionUtils {
public static boolean isEmpty(Map map) {
return map == null || map.size() == 0;
}
public static boolean isEmpty(List list) {
return list == null || list.size() == 0;
}
public static boolean isEmpty(Set set) {
return set == null || set.size() == 0;
}
public static boolean isNotEmpty(List list) {
return !isEmpty(list);
}
public static boolean isNotEmpty(Set set) {
return !isEmpty(set);
}
public static boolean isNotEmpty(Map map) {
return !isEmpty(map);
}
public static <T> boolean isNotEmpty(T[] array) {
return array != null && array.length > 0;
}
}

View File

@ -0,0 +1,37 @@
/*
* 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.library.util;
import java.io.*;
import java.net.URL;
/**
* @author peng-yongsheng
*/
public class ResourceUtils {
public static Reader read(String fileName) throws FileNotFoundException {
URL url = ResourceUtils.class.getClassLoader().getResource(fileName);
if (url == null) {
throw new FileNotFoundException("file not found: " + fileName);
}
InputStream inputStream = ResourceUtils.class.getClassLoader().getResourceAsStream(fileName);
return new InputStreamReader(inputStream);
}
}

View File

@ -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.library.util;
/**
* @author peng-yongsheng
*/
public class StringUtils {
public static final String EMPTY_STRING = "";
public static boolean isEmpty(Object str) {
return str == null || EMPTY_STRING.equals(str);
}
public static boolean isNotEmpty(Object str) {
return !isEmpty(str);
}
}

View File

@ -0,0 +1,37 @@
<?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>oap-server</artifactId>
<groupId>org.apache.skywalking</groupId>
<version>6.0.0-alpha-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>server-library</artifactId>
<packaging>pom</packaging>
<modules>
<module>library-module</module>
<module>library-util</module>
</modules>
</project>

View File

@ -0,0 +1,54 @@
<?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>oap-server</artifactId>
<groupId>org.apache.skywalking</groupId>
<version>6.0.0-alpha-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>server-starter</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>cluster-standalone-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>cluster-zookeeper-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>library-util</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -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.starter;
import java.util.concurrent.TimeUnit;
import org.apache.skywalking.oap.server.library.module.*;
import org.apache.skywalking.oap.server.starter.config.*;
import org.slf4j.*;
/**
* @author peng-yongsheng
*/
public class OAPBootStartUp {
private static final Logger logger = LoggerFactory.getLogger(OAPBootStartUp.class);
public static void main(String[] args) {
ApplicationConfigLoader configLoader = new ApplicationConfigLoader();
ModuleManager manager = new ModuleManager();
try {
ApplicationConfiguration applicationConfiguration = configLoader.load();
manager.init(applicationConfiguration);
} catch (ConfigFileNotFoundException | ModuleNotFoundException | ProviderNotFoundException | ServiceNotProvidedException | ModuleConfigException | ModuleStartException | DuplicateProviderException e) {
logger.error(e.getMessage(), e);
System.exit(1);
}
try {
TimeUnit.MINUTES.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,128 @@
/*
* 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.starter.config;
import java.io.*;
import java.util.*;
import org.apache.skywalking.oap.server.library.module.ApplicationConfiguration;
import org.apache.skywalking.oap.server.library.util.*;
import org.slf4j.*;
import org.yaml.snakeyaml.Yaml;
/**
* Initialize collector settings with following sources.
* Use application.yml as primary setting,
* and fix missing setting by default settings in application-default.yml.
*
* At last, override setting by system.properties and system.envs if the key matches moduleName.provideName.settingKey.
*
* @author peng-yongsheng, wusheng
*/
public class ApplicationConfigLoader implements ConfigLoader<ApplicationConfiguration> {
private static final Logger logger = LoggerFactory.getLogger(ApplicationConfigLoader.class);
private final Yaml yaml = new Yaml();
@Override public ApplicationConfiguration load() throws ConfigFileNotFoundException {
ApplicationConfiguration configuration = new ApplicationConfiguration();
this.loadConfig(configuration);
this.overrideConfigBySystemEnv(configuration);
return configuration;
}
@SuppressWarnings("unchecked")
private void loadConfig(ApplicationConfiguration configuration) throws ConfigFileNotFoundException {
try {
Reader applicationReader = ResourceUtils.read("application.yml");
Map<String, Map<String, Map<String, ?>>> moduleConfig = yaml.loadAs(applicationReader, Map.class);
if (CollectionUtils.isNotEmpty(moduleConfig)) {
moduleConfig.forEach((moduleName, providerConfig) -> {
if (providerConfig.size() > 0) {
logger.info("Get a module define from application.yml, module name: {}", moduleName);
ApplicationConfiguration.ModuleConfiguration moduleConfiguration = configuration.addModule(moduleName);
providerConfig.forEach((name, propertiesConfig) -> {
logger.info("Get a provider define belong to {} module, provider name: {}", moduleName, name);
Properties properties = new Properties();
if (propertiesConfig != null) {
propertiesConfig.forEach((key, value) -> {
properties.put(key, value);
logger.info("The property with key: {}, value: {}, in {} provider", key, value, name);
});
}
moduleConfiguration.addProviderConfiguration(name, properties);
});
} else {
logger.warn("Get a module define from application.yml, but no provider define, use default, module name: {}", moduleName);
}
});
}
} catch (FileNotFoundException e) {
throw new ConfigFileNotFoundException(e.getMessage(), e);
}
}
private void overrideConfigBySystemEnv(ApplicationConfiguration configuration) {
for (Map.Entry<Object, Object> prop : System.getProperties().entrySet()) {
overrideModuleSettings(configuration, prop.getKey().toString(), prop.getValue().toString());
}
}
private void overrideModuleSettings(ApplicationConfiguration configuration, String key, String value) {
int moduleAndConfigSeparator = key.indexOf('.');
if (moduleAndConfigSeparator <= 0) {
return;
}
String moduleName = key.substring(0, moduleAndConfigSeparator);
String providerSettingSubKey = key.substring(moduleAndConfigSeparator + 1);
ApplicationConfiguration.ModuleConfiguration moduleConfiguration = configuration.getModuleConfiguration(moduleName);
if (moduleConfiguration == null) {
return;
}
int providerAndConfigSeparator = providerSettingSubKey.indexOf('.');
if (providerAndConfigSeparator <= 0) {
return;
}
String providerName = providerSettingSubKey.substring(0, providerAndConfigSeparator);
String settingKey = providerSettingSubKey.substring(providerAndConfigSeparator + 1);
if (!moduleConfiguration.has(providerName)) {
return;
}
Properties providerSettings = moduleConfiguration.getProviderConfiguration(providerName);
if (!providerSettings.containsKey(settingKey)) {
return;
}
Object originValue = providerSettings.get(settingKey);
Class<?> type = originValue.getClass();
if (type.equals(int.class) || type.equals(Integer.class))
providerSettings.put(settingKey, Integer.valueOf(value));
else if (type.equals(String.class))
providerSettings.put(settingKey, value);
else if (type.equals(long.class) || type.equals(Long.class))
providerSettings.put(settingKey, Long.valueOf(value));
else if (type.equals(boolean.class) || type.equals(Boolean.class)) {
providerSettings.put(settingKey, Boolean.valueOf(value));
} else {
return;
}
logger.info("The setting has been override by key: {}, value: {}, in {} provider of {} module through {}",
settingKey, value, providerName, moduleName, "System.properties");
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.starter.config;
/**
* @author peng-yongsheng
*/
public class ConfigFileNotFoundException extends Exception {
public ConfigFileNotFoundException(String message) {
super(message);
}
public ConfigFileNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,26 @@
/*
* 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.starter.config;
/**
* @author peng-yongsheng
*/
public interface ConfigLoader<T> {
T load() throws ConfigFileNotFoundException;
}

View File

@ -0,0 +1,28 @@
# 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.
cluster:
zookeeper:
hostPort: localhost:2181
# Retry Policy
baseSleepTimeMs: 1000 # initial amount of time to wait between retries
maxRetries: 3 # max number of times to retry
#naming:
# jetty:
# #OS real network IP(binding required), for agent to find collector cluster
# host: localhost
# port: 10800
# contextPath: /

View File

@ -0,0 +1,37 @@
<?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>
<logger name="org.eclipse.jetty" level="INFO"/>
<logger name="org.apache.zookeeper" level="INFO"/>
<logger name="org.elasticsearch.common.network.IfConfig" level="INFO"/>
<logger name="org.apache.skywalking.apm.collector.agent.grpc.provider.handler.JVMMetricsServiceHandler" level="INFO"/>
<logger name="org.apache.skywalking.apm.collector.analysis.worker.timer.PersistenceTimer" level="INFO"/>
<logger name="io.grpc.netty" level="INFO"/>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>

42
pom.xml
View File

@ -17,7 +17,8 @@
~
-->
<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">
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.skywalking</groupId>
@ -58,6 +59,7 @@
</developers>
<modules>
<module>oap-server</module>
<module>apm-commons</module>
<module>apm-sniffer</module>
<module>apm-application-toolkit</module>
@ -119,29 +121,54 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
@ -299,6 +326,11 @@
<artifactId>apm-checkstyle</artifactId>
<version>5.0.0-beta</version>
</dependency>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>8.11</version>
</dependency>
</dependencies>
<executions>
<execution>