You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@skywalking.apache.org by wu...@apache.org on 2018/06/18 15:36:19 UTC
[incubator-skywalking] branch master updated: Zipkin receiver in
SkyWalking collector (#1273)
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git
The following commit(s) were added to refs/heads/master by this push:
new ecc0f94 Zipkin receiver in SkyWalking collector (#1273)
ecc0f94 is described below
commit ecc0f944d459aea437c800bdf50e4d28c4bbd846
Author: 吴晟 Wu Sheng <wu...@foxmail.com>
AuthorDate: Mon Jun 18 23:36:15 2018 +0800
Zipkin receiver in SkyWalking collector (#1273)
* Add Zipkin receiver
---
README.md | 13 +-
README_ZH.md | 22 +-
.../handler/InstanceDiscoveryServiceHandler.java | 26 +-
.../handler/naming/AgentGRPCNamingHandler.java | 5 +-
.../InstanceDiscoveryServiceHandlerTest.java | 47 +-
.../handler/ApplicationRegisterServletHandler.java | 4 +-
.../handler/InstanceDiscoveryServletHandler.java | 10 +-
.../handler/InstanceHeartBeatServletHandler.java | 4 +-
.../NetworkAddressRegisterServletHandler.java | 4 +-
.../ServiceNameDiscoveryServiceHandler.java | 4 +-
.../handler/TraceSegmentServletHandler.java | 4 +-
.../handler/naming/AgentJettyNamingHandler.java | 4 +-
.../register/define/service/AgentOsInfo.java | 84 ++++
.../define/service/IInstanceIDService.java | 2 +-
.../provider/service/InstanceIDService.java | 5 +-
.../parser/provider/parser/SegmentParse.java | 35 +-
apm-collector/apm-collector-boot/pom.xml | 8 +-
.../src/main/resources/application.yml | 8 +-
.../apm/collector/server/jetty/JettyHandler.java | 157 +------
.../{JettyHandler.java => JettyJsonHandler.java} | 24 +-
.../apm-collector-thirdparty-receiver/pom.xml | 37 ++
.../receiver-zipkin/docs/README.md | 25 ++
.../receiver-zipkin/pom.xml | 44 ++
.../receiver-zipkin/receiver-zipkin-define/pom.xml | 33 ++
.../zipkin/define/ZipkinReceiverModule.java} | 24 +-
...ywalking.apm.collector.core.module.ModuleDefine | 19 +
.../receiver-zipkin-provider/pom.xml | 68 +++
.../zipkin/provider/Receiver2AnalysisBridge.java | 48 +++
.../receiver/zipkin/provider/RegisterServices.java | 78 ++++
.../zipkin/provider/ZipkinReceiverConfig.java} | 28 +-
.../zipkin/provider/ZipkinReceiverProvider.java | 91 ++++
.../zipkin/provider/cache/CacheFactory.java} | 27 +-
.../zipkin/provider/cache/ISpanCache.java} | 12 +-
.../provider/cache/caffeine/CaffeineSpanCache.java | 99 +++++
.../zipkin/provider/data/SkyWalkingTrace.java | 58 +++
.../receiver/zipkin/provider/data/ZipkinTrace.java | 63 +++
.../zipkin/provider/handler/SpanProcessor.java | 54 +++
.../provider/handler/SpanV1JettyHandler.java | 71 +++
.../provider/handler/SpanV2JettyHandler.java | 73 ++++
.../zipkin/provider/transform/SegmentBuilder.java | 477 +++++++++++++++++++++
.../provider/transform/SegmentListener.java} | 13 +-
.../transform/Zipkin2SkyWalkingTransfer.java | 67 +++
...alking.apm.collector.core.module.ModuleProvider | 19 +
.../transform/SpringSleuthSegmentBuilderTest.java | 196 +++++++++
.../collector/ui/jetty/handler/GraphQLHandler.java | 4 +-
.../jetty/handler/naming/UIJettyNamingHandler.java | 4 +-
apm-collector/pom.xml | 7 +
apm-dist/release-docs/LICENSE | 1 +
docs/README.md | 1 +
docs/en/Incubating/Abstract.md | 1 +
50 files changed, 1913 insertions(+), 299 deletions(-)
diff --git a/README.md b/README.md
index 5dd896a..52de90d 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-Apache SkyWalking | [中文](README_ZH.md)
+Apache SkyWalking
==========
<img src="https://skywalkingtest.github.io/page-resources/3.0/skywalking.png" alt="Sky Walking logo" height="90px" align="right" />
@@ -40,6 +40,9 @@ including:
- Modern and cool Web UI
- Log integration
- Alarm for slow or unstable(low SLA) application, instance and service
+- [**Incubating**] Support accepting other tracer data formats.
+ - Zipkin JSON, Thrift, Protobuf v1 and v2 formats, powered by [OpenZipkin](https://github.com/openzipkin/zipkin) libs
+ - Jaeger in [Zipkin Thrift or JSON v1/v2 formats](https://github.com/jaegertracing/jaeger#backwards-compatibility-with-zipkin)
# Document
- [Documents in English](docs/README.md)
@@ -53,7 +56,6 @@ This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDU
# Live Demo
- Host in Beijing. [goto](http://49.4.12.44:8080/)
-- Host in HK. [goto](http://159.138.0.181:8080/)
# Screenshot
<img src="https://skywalkingtest.github.io/page-resources/5.0.0-beta/Dashboard.png"/>
@@ -61,11 +63,8 @@ This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDU
- [See all screenshots](/docs/Screenshots.md)
-# Test reports
-- Automatic integration test reports
- - [Java Agent test report](https://github.com/SkywalkingTest/agent-integration-test-report)
-- Performance test reports
- - [Java Agent test report](https://skywalkingtest.github.io/Agent-Benchmarks/)
+# Compiling project
+Follow this [document](https://github.com/apache/incubator-skywalking/blob/master/docs/en/How-to-build.md).
# Contact Us
* Submit an issue
diff --git a/README_ZH.md b/README_ZH.md
index a61cd47..d93527f 100644
--- a/README_ZH.md
+++ b/README_ZH.md
@@ -38,6 +38,9 @@ Apache SkyWalking | [English](README.md)
- 现代化Web UI
- 日志集成
- 应用、实例和服务的告警
+- [**Incubating**]支持接口其他探针的数据
+ - 接受Zipkin v1 v2格式数据,采用JSON, Thrift, Protobuf序列化方式。Powered by [OpenZipkin](https://github.com/openzipkin/zipkin) libs
+ - 接受Jaeger 使用 [Zipkin Thrift 或 JSON v1/v2 格式](https://github.com/jaegertracing/jaeger#backwards-compatibility-with-zipkin)
# Document
- [英文文档](docs/README.md)
@@ -52,7 +55,6 @@ This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDU
# Live Demo
- 北京服务器. [前往](http://49.4.12.44:8080/)
-- 香港服务器. [前往](http://159.138.0.181:8080/)
# Screenshot
<img src="https://skywalkingtest.github.io/page-resources/5.0.0-beta/Dashboard.png"/>
@@ -60,16 +62,8 @@ This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDU
- [查看所有系统截图](/docs/Screenshots.md)
-# Test reports
-- 自动化集成测试报告
- - [Java探针测试报告](https://github.com/SkywalkingTest/agent-integration-test-report)
-- 性能测试报告
- - [Java探针测试报告](https://skywalkingtest.github.io/Agent-Benchmarks/)
-
-# Users
-<img src="https://skywalkingtest.github.io/page-resources/users/users-2018-06-07.png"/>
-
-[报告新的用户案例](https://github.com/apache/incubator-skywalking/issues/443)
+# Compiling project
+查看[编译指南](https://github.com/apache/incubator-skywalking/blob/master/docs/cn/How-to-build-CN.md)
# Contact Us
* 直接提交Issue
@@ -77,5 +71,11 @@ This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDU
* [Gitter](https://gitter.im/openskywalking/Lobby)
* QQ群: 392443393
+# Users
+<img src="https://skywalkingtest.github.io/page-resources/users/users-2018-06-07.png"/>
+
+[报告新的用户案例](https://github.com/apache/incubator-skywalking/issues/443)
+
+
# License
[Apache 2.0 License.](/LICENSE)
diff --git a/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/main/java/org/apache/skywalking/apm/collector/agent/grpc/provider/handler/InstanceDiscoveryServiceHandler.java b/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/main/java/org/apache/skywalking/apm/collector/agent/grpc/provider/handler/InstanceDiscoveryServiceHandler.java
index 7f1f9c9..9fec7e9 100644
--- a/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/main/java/org/apache/skywalking/apm/collector/agent/grpc/provider/handler/InstanceDiscoveryServiceHandler.java
+++ b/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/main/java/org/apache/skywalking/apm/collector/agent/grpc/provider/handler/InstanceDiscoveryServiceHandler.java
@@ -18,12 +18,11 @@
package org.apache.skywalking.apm.collector.agent.grpc.provider.handler;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonObject;
import io.grpc.stub.StreamObserver;
import org.apache.skywalking.apm.collector.analysis.metric.define.AnalysisMetricModule;
import org.apache.skywalking.apm.collector.analysis.metric.define.service.IInstanceHeartBeatService;
import org.apache.skywalking.apm.collector.analysis.register.define.AnalysisRegisterModule;
+import org.apache.skywalking.apm.collector.analysis.register.define.service.AgentOsInfo;
import org.apache.skywalking.apm.collector.analysis.register.define.service.IInstanceIDService;
import org.apache.skywalking.apm.collector.core.module.ModuleManager;
import org.apache.skywalking.apm.collector.server.grpc.GRPCHandler;
@@ -54,7 +53,14 @@ public class InstanceDiscoveryServiceHandler extends InstanceDiscoveryServiceGrp
@Override
public void registerInstance(ApplicationInstance request,
StreamObserver<ApplicationInstanceMapping> responseObserver) {
- int instanceId = instanceIDService.getOrCreateByAgentUUID(request.getApplicationId(), request.getAgentUUID(), request.getRegisterTime(), buildOsInfo(request.getOsinfo()));
+ OSInfo osinfo = request.getOsinfo();
+ AgentOsInfo agentOsInfo = new AgentOsInfo();
+ agentOsInfo.setHostname(osinfo.getHostname());
+ agentOsInfo.setOsName(osinfo.getOsName());
+ agentOsInfo.setProcessNo(osinfo.getProcessNo());
+ agentOsInfo.setIpv4s(osinfo.getIpv4SList());
+
+ int instanceId = instanceIDService.getOrCreateByAgentUUID(request.getApplicationId(), request.getAgentUUID(), request.getRegisterTime(), agentOsInfo);
ApplicationInstanceMapping.Builder builder = ApplicationInstanceMapping.newBuilder();
builder.setApplicationId(request.getApplicationId());
builder.setApplicationInstanceId(instanceId);
@@ -69,18 +75,4 @@ public class InstanceDiscoveryServiceHandler extends InstanceDiscoveryServiceGrp
responseObserver.onNext(Downstream.getDefaultInstance());
responseObserver.onCompleted();
}
-
- private String buildOsInfo(OSInfo osinfo) {
- JsonObject osInfoJson = new JsonObject();
- osInfoJson.addProperty("osName", osinfo.getOsName());
- osInfoJson.addProperty("hostName", osinfo.getHostname());
- osInfoJson.addProperty("processId", osinfo.getProcessNo());
-
- JsonArray ipv4Array = new JsonArray();
- for (String ipv4 : osinfo.getIpv4SList()) {
- ipv4Array.add(ipv4);
- }
- osInfoJson.add("ipv4s", ipv4Array);
- return osInfoJson.toString();
- }
}
diff --git a/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/main/java/org/apache/skywalking/apm/collector/agent/grpc/provider/handler/naming/AgentGRPCNamingHandler.java b/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/main/java/org/apache/skywalking/apm/collector/agent/grpc/provider/handler/naming/AgentGRPCNamingHandler.java
index 3d5ce31..cf505d0 100644
--- a/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/main/java/org/apache/skywalking/apm/collector/agent/grpc/provider/handler/naming/AgentGRPCNamingHandler.java
+++ b/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/main/java/org/apache/skywalking/apm/collector/agent/grpc/provider/handler/naming/AgentGRPCNamingHandler.java
@@ -16,7 +16,6 @@
*
*/
-
package org.apache.skywalking.apm.collector.agent.grpc.provider.handler.naming;
import com.google.gson.JsonArray;
@@ -24,12 +23,12 @@ import com.google.gson.JsonElement;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.skywalking.apm.collector.server.jetty.ArgumentsParseException;
-import org.apache.skywalking.apm.collector.server.jetty.JettyHandler;
+import org.apache.skywalking.apm.collector.server.jetty.JettyJsonHandler;
/**
* @author peng-yongsheng
*/
-public class AgentGRPCNamingHandler extends JettyHandler {
+public class AgentGRPCNamingHandler extends JettyJsonHandler {
private final AgentGRPCNamingListener namingListener;
diff --git a/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/test/java/org/apache/skywalking/apm/collector/agent/grpc/provider/handler/InstanceDiscoveryServiceHandlerTest.java b/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/test/java/org/apache/skywalking/apm/collector/agent/grpc/provider/handler/InstanceDiscoveryServiceHandlerTest.java
index d3ab080..a7484c8 100644
--- a/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/test/java/org/apache/skywalking/apm/collector/agent/grpc/provider/handler/InstanceDiscoveryServiceHandlerTest.java
+++ b/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/test/java/org/apache/skywalking/apm/collector/agent/grpc/provider/handler/InstanceDiscoveryServiceHandlerTest.java
@@ -18,11 +18,16 @@
package org.apache.skywalking.apm.collector.agent.grpc.provider.handler;
import io.grpc.stub.StreamObserver;
+import java.util.UUID;
import org.apache.skywalking.apm.collector.analysis.metric.define.service.IInstanceHeartBeatService;
import org.apache.skywalking.apm.collector.analysis.register.define.service.IInstanceIDService;
import org.apache.skywalking.apm.collector.core.module.MockModule;
import org.apache.skywalking.apm.collector.core.module.ModuleManager;
-import org.apache.skywalking.apm.network.proto.*;
+import org.apache.skywalking.apm.network.proto.ApplicationInstance;
+import org.apache.skywalking.apm.network.proto.ApplicationInstanceHeartbeat;
+import org.apache.skywalking.apm.network.proto.ApplicationInstanceMapping;
+import org.apache.skywalking.apm.network.proto.Downstream;
+import org.apache.skywalking.apm.network.proto.OSInfo;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -31,11 +36,9 @@ import org.mockito.Mock;
import org.mockito.internal.util.reflection.Whitebox;
import org.mockito.runners.MockitoJUnitRunner;
-import java.util.UUID;
-
-import static org.junit.Assert.*;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;
@@ -65,22 +68,22 @@ public class InstanceDiscoveryServiceHandlerTest {
@Test
public void registerInstance() {
ApplicationInstance applicationInstance = ApplicationInstance.newBuilder()
- .setAgentUUID(UUID.randomUUID().toString())
- .setApplicationId(10)
- .setRegisterTime(System.currentTimeMillis())
- .setOsinfo(
- OSInfo.newBuilder()
- .setOsName("MAC OS")
- .setHostname("test")
- .addIpv4S("127.0.0.1")
- .setProcessNo(123456)
- .build()
- ).build();
- when(instanceIDService.getOrCreateByAgentUUID(anyInt(), anyString(), anyLong(), anyString())).thenReturn(100);
+ .setAgentUUID(UUID.randomUUID().toString())
+ .setApplicationId(10)
+ .setRegisterTime(System.currentTimeMillis())
+ .setOsinfo(
+ OSInfo.newBuilder()
+ .setOsName("MAC OS")
+ .setHostname("test")
+ .addIpv4S("127.0.0.1")
+ .setProcessNo(123456)
+ .build()
+ ).build();
+ when(instanceIDService.getOrCreateByAgentUUID(anyInt(), anyString(), anyLong(), anyObject())).thenReturn(100);
instanceDiscoveryServiceHandler.registerInstance(applicationInstance, new StreamObserver<ApplicationInstanceMapping>() {
@Override
public void onNext(ApplicationInstanceMapping applicationInstanceMapping) {
- Assert.assertEquals(100,applicationInstanceMapping.getApplicationInstanceId());
+ Assert.assertEquals(100, applicationInstanceMapping.getApplicationInstanceId());
}
@Override
@@ -98,13 +101,13 @@ public class InstanceDiscoveryServiceHandlerTest {
@Test
public void heartbeat() {
ApplicationInstanceHeartbeat heartbeat = ApplicationInstanceHeartbeat.newBuilder()
- .setApplicationInstanceId(100)
- .setHeartbeatTime(System.currentTimeMillis())
- .build();
+ .setApplicationInstanceId(100)
+ .setHeartbeatTime(System.currentTimeMillis())
+ .build();
instanceDiscoveryServiceHandler.heartbeat(heartbeat, new StreamObserver<Downstream>() {
@Override
public void onNext(Downstream downstream) {
- Assert.assertEquals(Downstream.getDefaultInstance(),downstream);
+ Assert.assertEquals(Downstream.getDefaultInstance(), downstream);
}
@Override
@@ -118,4 +121,4 @@ public class InstanceDiscoveryServiceHandlerTest {
}
});
}
-}
\ No newline at end of file
+}
diff --git a/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/ApplicationRegisterServletHandler.java b/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/ApplicationRegisterServletHandler.java
index c60f4b6..100692d 100644
--- a/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/ApplicationRegisterServletHandler.java
+++ b/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/ApplicationRegisterServletHandler.java
@@ -28,14 +28,14 @@ import org.apache.skywalking.apm.collector.analysis.register.define.AnalysisRegi
import org.apache.skywalking.apm.collector.analysis.register.define.service.IApplicationIDService;
import org.apache.skywalking.apm.collector.core.module.ModuleManager;
import org.apache.skywalking.apm.collector.server.jetty.ArgumentsParseException;
-import org.apache.skywalking.apm.collector.server.jetty.JettyHandler;
+import org.apache.skywalking.apm.collector.server.jetty.JettyJsonHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author peng-yongsheng
*/
-public class ApplicationRegisterServletHandler extends JettyHandler {
+public class ApplicationRegisterServletHandler extends JettyJsonHandler {
private static final Logger logger = LoggerFactory.getLogger(ApplicationRegisterServletHandler.class);
diff --git a/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/InstanceDiscoveryServletHandler.java b/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/InstanceDiscoveryServletHandler.java
index d88d86c..d0a1a08 100644
--- a/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/InstanceDiscoveryServletHandler.java
+++ b/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/InstanceDiscoveryServletHandler.java
@@ -24,17 +24,18 @@ import com.google.gson.JsonObject;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.apache.skywalking.apm.collector.analysis.register.define.AnalysisRegisterModule;
+import org.apache.skywalking.apm.collector.analysis.register.define.service.AgentOsInfo;
import org.apache.skywalking.apm.collector.analysis.register.define.service.IInstanceIDService;
import org.apache.skywalking.apm.collector.core.module.ModuleManager;
import org.apache.skywalking.apm.collector.server.jetty.ArgumentsParseException;
-import org.apache.skywalking.apm.collector.server.jetty.JettyHandler;
+import org.apache.skywalking.apm.collector.server.jetty.JettyJsonHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author peng-yongsheng
*/
-public class InstanceDiscoveryServletHandler extends JettyHandler {
+public class InstanceDiscoveryServletHandler extends JettyJsonHandler {
private static final Logger logger = LoggerFactory.getLogger(InstanceDiscoveryServletHandler.class);
@@ -66,9 +67,10 @@ public class InstanceDiscoveryServletHandler extends JettyHandler {
int applicationId = instance.get(APPLICATION_ID).getAsInt();
String agentUUID = instance.get(AGENT_UUID).getAsString();
long registerTime = instance.get(REGISTER_TIME).getAsLong();
- JsonObject osInfo = instance.get(OS_INFO).getAsJsonObject();
+ JsonObject osInfoJson = instance.get(OS_INFO).getAsJsonObject();
+ AgentOsInfo osInfo = gson.fromJson(osInfoJson, AgentOsInfo.class);
- int instanceId = instanceIDService.getOrCreateByAgentUUID(applicationId, agentUUID, registerTime, osInfo.toString());
+ int instanceId = instanceIDService.getOrCreateByAgentUUID(applicationId, agentUUID, registerTime, osInfo);
responseJson.addProperty(APPLICATION_ID, applicationId);
responseJson.addProperty(INSTANCE_ID, instanceId);
} catch (IOException e) {
diff --git a/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/InstanceHeartBeatServletHandler.java b/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/InstanceHeartBeatServletHandler.java
index acc479a..32841b9 100644
--- a/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/InstanceHeartBeatServletHandler.java
+++ b/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/InstanceHeartBeatServletHandler.java
@@ -27,14 +27,14 @@ import org.apache.skywalking.apm.collector.analysis.metric.define.AnalysisMetric
import org.apache.skywalking.apm.collector.analysis.metric.define.service.IInstanceHeartBeatService;
import org.apache.skywalking.apm.collector.core.module.ModuleManager;
import org.apache.skywalking.apm.collector.server.jetty.ArgumentsParseException;
-import org.apache.skywalking.apm.collector.server.jetty.JettyHandler;
+import org.apache.skywalking.apm.collector.server.jetty.JettyJsonHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author peng-yongsheng
*/
-public class InstanceHeartBeatServletHandler extends JettyHandler {
+public class InstanceHeartBeatServletHandler extends JettyJsonHandler {
private static final Logger logger = LoggerFactory.getLogger(InstanceHeartBeatServletHandler.class);
diff --git a/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/NetworkAddressRegisterServletHandler.java b/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/NetworkAddressRegisterServletHandler.java
index 318c3fe..4fc8852 100644
--- a/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/NetworkAddressRegisterServletHandler.java
+++ b/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/NetworkAddressRegisterServletHandler.java
@@ -28,14 +28,14 @@ import org.apache.skywalking.apm.collector.analysis.register.define.AnalysisRegi
import org.apache.skywalking.apm.collector.analysis.register.define.service.INetworkAddressIDService;
import org.apache.skywalking.apm.collector.core.module.ModuleManager;
import org.apache.skywalking.apm.collector.server.jetty.ArgumentsParseException;
-import org.apache.skywalking.apm.collector.server.jetty.JettyHandler;
+import org.apache.skywalking.apm.collector.server.jetty.JettyJsonHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author peng-yongsheng
*/
-public class NetworkAddressRegisterServletHandler extends JettyHandler {
+public class NetworkAddressRegisterServletHandler extends JettyJsonHandler {
private static final Logger logger = LoggerFactory.getLogger(NetworkAddressRegisterServletHandler.class);
diff --git a/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/ServiceNameDiscoveryServiceHandler.java b/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/ServiceNameDiscoveryServiceHandler.java
index 6ddce79..4bc4ac7 100644
--- a/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/ServiceNameDiscoveryServiceHandler.java
+++ b/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/ServiceNameDiscoveryServiceHandler.java
@@ -28,14 +28,14 @@ import org.apache.skywalking.apm.collector.analysis.register.define.AnalysisRegi
import org.apache.skywalking.apm.collector.analysis.register.define.service.IServiceNameService;
import org.apache.skywalking.apm.collector.core.module.ModuleManager;
import org.apache.skywalking.apm.collector.server.jetty.ArgumentsParseException;
-import org.apache.skywalking.apm.collector.server.jetty.JettyHandler;
+import org.apache.skywalking.apm.collector.server.jetty.JettyJsonHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author peng-yongsheng
*/
-public class ServiceNameDiscoveryServiceHandler extends JettyHandler {
+public class ServiceNameDiscoveryServiceHandler extends JettyJsonHandler {
private static final Logger logger = LoggerFactory.getLogger(ServiceNameDiscoveryServiceHandler.class);
diff --git a/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/TraceSegmentServletHandler.java b/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/TraceSegmentServletHandler.java
index fec68ef..169329b 100644
--- a/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/TraceSegmentServletHandler.java
+++ b/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/TraceSegmentServletHandler.java
@@ -29,14 +29,14 @@ import org.apache.skywalking.apm.collector.analysis.segment.parser.define.Analys
import org.apache.skywalking.apm.collector.analysis.segment.parser.define.service.ISegmentParseService;
import org.apache.skywalking.apm.collector.core.module.ModuleManager;
import org.apache.skywalking.apm.collector.server.jetty.ArgumentsParseException;
-import org.apache.skywalking.apm.collector.server.jetty.JettyHandler;
+import org.apache.skywalking.apm.collector.server.jetty.JettyJsonHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author peng-yongsheng
*/
-public class TraceSegmentServletHandler extends JettyHandler {
+public class TraceSegmentServletHandler extends JettyJsonHandler {
private static final Logger logger = LoggerFactory.getLogger(TraceSegmentServletHandler.class);
diff --git a/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/naming/AgentJettyNamingHandler.java b/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/naming/AgentJettyNamingHandler.java
index cf63350..f9114c6 100644
--- a/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/naming/AgentJettyNamingHandler.java
+++ b/apm-collector/apm-collector-agent/agent-jetty/agent-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/agent/jetty/provider/handler/naming/AgentJettyNamingHandler.java
@@ -24,12 +24,12 @@ import com.google.gson.JsonElement;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.skywalking.apm.collector.server.jetty.ArgumentsParseException;
-import org.apache.skywalking.apm.collector.server.jetty.JettyHandler;
+import org.apache.skywalking.apm.collector.server.jetty.JettyJsonHandler;
/**
* @author peng-yongsheng
*/
-public class AgentJettyNamingHandler extends JettyHandler {
+public class AgentJettyNamingHandler extends JettyJsonHandler {
private final AgentJettyNamingListener namingListener;
diff --git a/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/AgentOsInfo.java b/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/AgentOsInfo.java
new file mode 100644
index 0000000..b16f843
--- /dev/null
+++ b/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/AgentOsInfo.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.collector.analysis.register.define.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import java.util.List;
+
+/**
+ * @author wusheng
+ */
+public class AgentOsInfo {
+ private String osName;
+ private String hostname;
+ private int processNo;
+ private List<String> ipv4s;
+
+ public AgentOsInfo() {
+ }
+
+ public String getOsName() {
+ return osName;
+ }
+
+ public void setOsName(String osName) {
+ this.osName = osName;
+ }
+
+ public String getHostname() {
+ return hostname;
+ }
+
+ public void setHostname(String hostname) {
+ this.hostname = hostname;
+ }
+
+ public int getProcessNo() {
+ return processNo;
+ }
+
+ public void setProcessNo(int processNo) {
+ this.processNo = processNo;
+ }
+
+ public List<String> getIpv4s() {
+ return ipv4s;
+ }
+
+ public void setIpv4s(List<String> ipv4s) {
+ this.ipv4s = ipv4s;
+ }
+
+ @Override public String toString() {
+ JsonObject osInfoJson = new JsonObject();
+ osInfoJson.addProperty("osName", this.getOsName());
+ osInfoJson.addProperty("hostName", this.getHostname());
+ osInfoJson.addProperty("processId", this.getProcessNo());
+
+ JsonArray ipv4Array = new JsonArray();
+ if (this.getIpv4s() != null) {
+ for (String ipv4 : this.getIpv4s()) {
+ ipv4Array.add(ipv4);
+ }
+ }
+ osInfoJson.add("ipv4s", ipv4Array);
+ return osInfoJson.toString();
+ }
+}
diff --git a/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java b/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java
index ed84f05..8959b73 100644
--- a/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java
+++ b/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java
@@ -24,7 +24,7 @@ import org.apache.skywalking.apm.collector.core.module.Service;
* @author peng-yongsheng
*/
public interface IInstanceIDService extends Service {
- int getOrCreateByAgentUUID(int applicationId, String agentUUID, long registerTime, String osInfo);
+ int getOrCreateByAgentUUID(int applicationId, String agentUUID, long registerTime, AgentOsInfo osInfo);
int getOrCreateByAddressId(int applicationId, int addressId, long registerTime);
}
diff --git a/apm-collector/apm-collector-analysis/analysis-register/register-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/register/provider/service/InstanceIDService.java b/apm-collector/apm-collector-analysis/analysis-register/register-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/register/provider/service/InstanceIDService.java
index 293bad2..b4cbf98 100644
--- a/apm-collector/apm-collector-analysis/analysis-register/register-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/register/provider/service/InstanceIDService.java
+++ b/apm-collector/apm-collector-analysis/analysis-register/register-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/register/provider/service/InstanceIDService.java
@@ -19,6 +19,7 @@
package org.apache.skywalking.apm.collector.analysis.register.provider.service;
import org.apache.skywalking.apm.collector.analysis.register.define.graph.GraphIdDefine;
+import org.apache.skywalking.apm.collector.analysis.register.define.service.AgentOsInfo;
import org.apache.skywalking.apm.collector.analysis.register.define.service.IInstanceIDService;
import org.apache.skywalking.apm.collector.cache.CacheModule;
import org.apache.skywalking.apm.collector.cache.service.ApplicationCacheService;
@@ -71,7 +72,7 @@ public class InstanceIDService implements IInstanceIDService {
return applicationCacheService;
}
- @Override public int getOrCreateByAgentUUID(int applicationId, String agentUUID, long registerTime, String osInfo) {
+ @Override public int getOrCreateByAgentUUID(int applicationId, String agentUUID, long registerTime, AgentOsInfo osInfo) {
logger.debug("get or getOrCreate instance id by agent UUID, application id: {}, agentUUID: {}, registerTime: {}, osInfo: {}", applicationId, agentUUID, registerTime, osInfo);
int instanceId = getInstanceCacheService().getInstanceIdByAgentUUID(applicationId, agentUUID);
@@ -84,7 +85,7 @@ public class InstanceIDService implements IInstanceIDService {
instance.setRegisterTime(registerTime);
instance.setHeartBeatTime(registerTime);
instance.setInstanceId(0);
- instance.setOsInfo(osInfo);
+ instance.setOsInfo(osInfo.toString());
instance.setIsAddress(BooleanUtils.FALSE);
instance.setAddressId(Const.NONE);
diff --git a/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/parser/SegmentParse.java b/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/parser/SegmentParse.java
index 87b1e39..aaa0f83 100644
--- a/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/parser/SegmentParse.java
+++ b/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/parser/SegmentParse.java
@@ -19,20 +19,32 @@
package org.apache.skywalking.apm.collector.analysis.segment.parser.provider.parser;
import com.google.protobuf.InvalidProtocolBufferException;
-import java.util.*;
-import org.apache.skywalking.apm.collector.analysis.segment.parser.define.decorator.*;
+import org.apache.skywalking.apm.collector.analysis.segment.parser.define.decorator.ReferenceDecorator;
+import org.apache.skywalking.apm.collector.analysis.segment.parser.define.decorator.SegmentCoreInfo;
+import org.apache.skywalking.apm.collector.analysis.segment.parser.define.decorator.SegmentDecorator;
+import org.apache.skywalking.apm.collector.analysis.segment.parser.define.decorator.SpanDecorator;
import org.apache.skywalking.apm.collector.analysis.segment.parser.define.graph.GraphIdDefine;
import org.apache.skywalking.apm.collector.analysis.segment.parser.define.listener.*;
import org.apache.skywalking.apm.collector.analysis.segment.parser.define.service.ISegmentParseService;
-import org.apache.skywalking.apm.collector.analysis.segment.parser.provider.parser.standardization.*;
+import org.apache.skywalking.apm.collector.analysis.segment.parser.provider.parser.standardization.ReferenceIdExchanger;
+import org.apache.skywalking.apm.collector.analysis.segment.parser.provider.parser.standardization.SegmentStandardization;
+import org.apache.skywalking.apm.collector.analysis.segment.parser.provider.parser.standardization.SpanIdExchanger;
import org.apache.skywalking.apm.collector.core.UnexpectedException;
import org.apache.skywalking.apm.collector.core.annotations.trace.GraphComputingMetric;
-import org.apache.skywalking.apm.collector.core.graph.*;
+import org.apache.skywalking.apm.collector.core.graph.Graph;
+import org.apache.skywalking.apm.collector.core.graph.GraphManager;
import org.apache.skywalking.apm.collector.core.module.ModuleManager;
import org.apache.skywalking.apm.collector.core.util.TimeBucketUtils;
import org.apache.skywalking.apm.collector.storage.table.segment.Segment;
-import org.apache.skywalking.apm.network.proto.*;
-import org.slf4j.*;
+import org.apache.skywalking.apm.network.proto.SpanType;
+import org.apache.skywalking.apm.network.proto.TraceSegmentObject;
+import org.apache.skywalking.apm.network.proto.UniqueId;
+import org.apache.skywalking.apm.network.proto.UpstreamSegment;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.LinkedList;
+import java.util.List;
/**
* @author peng-yongsheng
@@ -193,7 +205,7 @@ public class SegmentParse {
private void notifyExitListener(SpanDecorator spanDecorator) {
spanListeners.forEach(listener -> {
if (listener.containsPoint(SpanListener.Point.Exit)) {
- ((ExitSpanListener)listener).parseExit(spanDecorator, segmentCoreInfo);
+ ((ExitSpanListener) listener).parseExit(spanDecorator, segmentCoreInfo);
}
});
}
@@ -202,7 +214,7 @@ public class SegmentParse {
private void notifyEntryListener(SpanDecorator spanDecorator) {
spanListeners.forEach(listener -> {
if (listener.containsPoint(SpanListener.Point.Entry)) {
- ((EntrySpanListener)listener).parseEntry(spanDecorator, segmentCoreInfo);
+ ((EntrySpanListener) listener).parseEntry(spanDecorator, segmentCoreInfo);
}
});
}
@@ -211,7 +223,7 @@ public class SegmentParse {
private void notifyLocalListener(SpanDecorator spanDecorator) {
spanListeners.forEach(listener -> {
if (listener.containsPoint(SpanListener.Point.Local)) {
- ((LocalSpanListener)listener).parseLocal(spanDecorator, segmentCoreInfo);
+ ((LocalSpanListener) listener).parseLocal(spanDecorator, segmentCoreInfo);
}
});
}
@@ -220,7 +232,7 @@ public class SegmentParse {
private void notifyFirstListener(SpanDecorator spanDecorator) {
spanListeners.forEach(listener -> {
if (listener.containsPoint(SpanListener.Point.First)) {
- ((FirstSpanListener)listener).parseFirst(spanDecorator, segmentCoreInfo);
+ ((FirstSpanListener) listener).parseFirst(spanDecorator, segmentCoreInfo);
}
});
}
@@ -229,7 +241,7 @@ public class SegmentParse {
private void notifyGlobalsListener(UniqueId uniqueId) {
spanListeners.forEach(listener -> {
if (listener.containsPoint(SpanListener.Point.GlobalTraceIds)) {
- ((GlobalTraceIdsListener)listener).parseGlobalTraceId(uniqueId, segmentCoreInfo);
+ ((GlobalTraceIdsListener) listener).parseGlobalTraceId(uniqueId, segmentCoreInfo);
}
});
}
@@ -238,4 +250,5 @@ public class SegmentParse {
private void createSpanListeners() {
listenerManager.getSpanListenerFactories().forEach(spanListenerFactory -> spanListeners.add(spanListenerFactory.create(moduleManager)));
}
+
}
diff --git a/apm-collector/apm-collector-boot/pom.xml b/apm-collector/apm-collector-boot/pom.xml
index 22981fc..6a06ebc 100644
--- a/apm-collector/apm-collector-boot/pom.xml
+++ b/apm-collector/apm-collector-boot/pom.xml
@@ -185,6 +185,12 @@
<version>${project.version}</version>
</dependency>
<!-- alarm provider -->
+ <!-- zipkin receiver-->
+ <dependency>
+ <groupId>org.apache.skywalking</groupId>
+ <artifactId>receiver-zipkin-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<!-- instrument provided dependency -->
<dependency>
@@ -246,4 +252,4 @@
</plugin>
</plugins>
</build>
-</project>
\ No newline at end of file
+</project>
diff --git a/apm-collector/apm-collector-boot/src/main/resources/application.yml b/apm-collector/apm-collector-boot/src/main/resources/application.yml
index 985ddbb..05f9e61 100644
--- a/apm-collector/apm-collector-boot/src/main/resources/application.yml
+++ b/apm-collector/apm-collector-boot/src/main/resources/application.yml
@@ -101,4 +101,10 @@ configuration:
thermodynamicResponseTimeStep: 50
thermodynamicCountOfResponseTimeSteps: 40
# max collection's size of worker cache collection, setting it smaller when collector OutOfMemory crashed.
- workerCacheMaxSize: 10000
\ No newline at end of file
+ workerCacheMaxSize: 10000
+#receiver_zipkin:
+# default:
+# host: localhost
+# port: 9411
+# contextPath: /
+#
\ No newline at end of file
diff --git a/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/jetty/JettyHandler.java b/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/jetty/JettyHandler.java
index 1f4e66e..6738ad4 100644
--- a/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/jetty/JettyHandler.java
+++ b/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/jetty/JettyHandler.java
@@ -18,167 +18,12 @@
package org.apache.skywalking.apm.collector.server.jetty;
-import com.google.gson.JsonElement;
-import org.apache.skywalking.apm.collector.server.ServerHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.*;
import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Enumeration;
-
-import static java.util.Objects.nonNull;
+import org.apache.skywalking.apm.collector.server.ServerHandler;
/**
* @author peng-yongsheng
*/
public abstract class JettyHandler extends HttpServlet implements ServerHandler {
-
- private static final Logger logger = LoggerFactory.getLogger(JettyHandler.class);
-
public abstract String pathSpec();
-
- @Override
- protected final void doGet(HttpServletRequest req, HttpServletResponse resp) {
- try {
- reply(resp, doGet(req));
- } catch (ArgumentsParseException | IOException e) {
- try {
- replyError(resp, e.getMessage(), HttpServletResponse.SC_BAD_REQUEST);
- } catch (IOException replyException) {
- logger.error(replyException.getMessage(), e);
- }
- }
- }
-
- protected abstract JsonElement doGet(HttpServletRequest req) throws ArgumentsParseException;
-
- @Override
- protected final void doPost(HttpServletRequest req, HttpServletResponse resp) {
- try {
- reply(resp, doPost(req));
- } catch (ArgumentsParseException | IOException e) {
- try {
- replyError(resp, e.getMessage(), HttpServletResponse.SC_BAD_REQUEST);
- } catch (IOException replyException) {
- logger.error(replyException.getMessage(), e);
- }
- }
- }
-
- protected abstract JsonElement doPost(HttpServletRequest req) throws ArgumentsParseException, IOException;
-
- @Override
- protected final void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- super.doHead(req, resp);
- }
-
- @Override protected final long getLastModified(HttpServletRequest req) {
- return super.getLastModified(req);
- }
-
- @Override
- protected final void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- super.doPut(req, resp);
- }
-
- @Override
- protected final void doDelete(HttpServletRequest req,
- HttpServletResponse resp) throws ServletException, IOException {
- super.doDelete(req, resp);
- }
-
- @Override
- protected final void doOptions(HttpServletRequest req,
- HttpServletResponse resp) throws ServletException, IOException {
- super.doOptions(req, resp);
- }
-
- @Override
- protected final void doTrace(HttpServletRequest req,
- HttpServletResponse resp) throws ServletException, IOException {
- super.doTrace(req, resp);
- }
-
- @Override
- protected final void service(HttpServletRequest req,
- HttpServletResponse resp) throws ServletException, IOException {
- super.service(req, resp);
- }
-
- @Override public final void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
- super.service(req, res);
- }
-
- @Override public final void destroy() {
- super.destroy();
- }
-
- @Override public final String getInitParameter(String name) {
- return super.getInitParameter(name);
- }
-
- @Override public final Enumeration<String> getInitParameterNames() {
- return super.getInitParameterNames();
- }
-
- @Override public final ServletConfig getServletConfig() {
- return super.getServletConfig();
- }
-
- @Override public final ServletContext getServletContext() {
- return super.getServletContext();
- }
-
- @Override public final String getServletInfo() {
- return super.getServletInfo();
- }
-
- @Override public final void init(ServletConfig config) throws ServletException {
- super.init(config);
- }
-
- @Override public final void init() throws ServletException {
- super.init();
- }
-
- @Override public final void log(String msg) {
- super.log(msg);
- }
-
- @Override public final void log(String message, Throwable t) {
- super.log(message, t);
- }
-
- @Override public final String getServletName() {
- return super.getServletName();
- }
-
- private void reply(HttpServletResponse response, JsonElement resJson) throws IOException {
- response.setContentType("application/json");
- response.setCharacterEncoding("utf-8");
- response.setStatus(HttpServletResponse.SC_OK);
-
- PrintWriter out = response.getWriter();
- if (nonNull(resJson)) {
- out.print(resJson);
- }
- out.flush();
- out.close();
- }
-
- private void replyError(HttpServletResponse response, String errorMessage, int status) throws IOException {
- response.setContentType("application/json");
- response.setCharacterEncoding("utf-8");
- response.setStatus(status);
- response.setHeader("error-message", errorMessage);
-
- PrintWriter out = response.getWriter();
- out.flush();
- out.close();
- }
}
diff --git a/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/jetty/JettyHandler.java b/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/jetty/JettyJsonHandler.java
similarity index 95%
copy from apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/jetty/JettyHandler.java
copy to apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/jetty/JettyJsonHandler.java
index 1f4e66e..f79f8c7 100644
--- a/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/jetty/JettyHandler.java
+++ b/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/jetty/JettyJsonHandler.java
@@ -19,29 +19,27 @@
package org.apache.skywalking.apm.collector.server.jetty;
import com.google.gson.JsonElement;
-import org.apache.skywalking.apm.collector.server.ServerHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.*;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import static java.util.Objects.nonNull;
/**
- * @author peng-yongsheng
+ * @author wusheng
*/
-public abstract class JettyHandler extends HttpServlet implements ServerHandler {
-
+public abstract class JettyJsonHandler extends JettyHandler {
private static final Logger logger = LoggerFactory.getLogger(JettyHandler.class);
- public abstract String pathSpec();
-
@Override
protected final void doGet(HttpServletRequest req, HttpServletResponse resp) {
try {
diff --git a/apm-collector/apm-collector-thirdparty-receiver/pom.xml b/apm-collector/apm-collector-thirdparty-receiver/pom.xml
new file mode 100644
index 0000000..4626467
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/pom.xml
@@ -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>apm-collector</artifactId>
+ <groupId>org.apache.skywalking</groupId>
+ <version>5.0.0-beta2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>apm-collector-thirdparty-receiver</artifactId>
+ <packaging>pom</packaging>
+ <modules>
+ <module>receiver-zipkin</module>
+ </modules>
+
+
+</project>
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/docs/README.md b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/docs/README.md
new file mode 100644
index 0000000..a1c5c6c
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/docs/README.md
@@ -0,0 +1,25 @@
+# Zipkin receiver
+[Zipkin](http://zipkin.io/) receiver provides the feature to receive span data in Zipkin formats. SkyWalking backend provides
+analysis, aggregation and visualization. So the user will not need to learn how SkyWalking auto instrumentation
+agents(Java, .NET, node.js) work, or they don't want to change for some reasons, such as Zipkin integration has been completed.
+
+Zipkin receiver is only an optional features in SkyWalking, even now it is [an incubating feature](../../../../docs/en/Incubating/Abstract.md).
+
+## Limits
+As an incubating feature, it is a prototype. So it has following limits:
+
+1. Don't try to use SkyWalking native agents and Zipkin's libs in the same distributed system. Considering HEADERs of Zipkin and SkyWalking aren't shared/interoperable, their two will not propagate context for each other. Trace will not continue.
+1. Don't support cluster mode.
+1. Analysis based on trace will be finished in the certain and given duration. The default assumption is 2 min most. SkyWalking used more complex header and context to avoid this in analysis stage.
+
+## Open Zipkin receiver
+Zipkin receiver is an optional module, and default closed. For open it, add these settings in your `application.yml` in collector
+```yaml
+receiver_zipkin:
+ default:
+ host: localhost
+ port: 9411
+ contextPath: /
+ expireTime: 20 # Unit is seconds
+ maxCacheSize: 1000000 # The number of traces in buffer
+```
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/pom.xml b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/pom.xml
new file mode 100644
index 0000000..4ed7017
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/pom.xml
@@ -0,0 +1,44 @@
+<?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-collector-thirdparty-receiver</artifactId>
+ <groupId>org.apache.skywalking</groupId>
+ <version>5.0.0-beta2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>receiver-zipkin</artifactId>
+ <packaging>pom</packaging>
+ <modules>
+ <module>receiver-zipkin-define</module>
+ <module>receiver-zipkin-provider</module>
+ </modules>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.skywalking</groupId>
+ <artifactId>apm-collector-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-define/pom.xml b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-define/pom.xml
new file mode 100644
index 0000000..e7d1282
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-define/pom.xml
@@ -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>
+ <artifactId>receiver-zipkin</artifactId>
+ <groupId>org.apache.skywalking</groupId>
+ <version>5.0.0-beta2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>receiver-zipkin-define</artifactId>
+
+
+</project>
diff --git a/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-define/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/define/ZipkinReceiverModule.java
similarity index 51%
copy from apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java
copy to apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-define/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/define/ZipkinReceiverModule.java
index ed84f05..c93c192 100644
--- a/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-define/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/define/ZipkinReceiverModule.java
@@ -16,15 +16,27 @@
*
*/
-package org.apache.skywalking.apm.collector.analysis.register.define.service;
+package org.apache.skywalking.apm.collector.receiver.zipkin.define;
-import org.apache.skywalking.apm.collector.core.module.Service;
+import org.apache.skywalking.apm.collector.core.module.ModuleDefine;
/**
- * @author peng-yongsheng
+ * Zipkin receiver module provides the HTTP, protoc serve for any SDK or agent by following Zipkin format.
+ *
+ * At this moment, Zipkin format is not compatible with SkyWalking, especially HEADERs.
+ * Please don't consider this as a Zipkin-SkyWalking integration,
+ * it is provided for adding analysis, aggregation and visualization capabilities to zipkin backend.
+ *
+ * @author wusheng
*/
-public interface IInstanceIDService extends Service {
- int getOrCreateByAgentUUID(int applicationId, String agentUUID, long registerTime, String osInfo);
+public class ZipkinReceiverModule extends ModuleDefine {
+ public static final String NAME = "receiver_zipkin";
+
+ @Override public String name() {
+ return NAME;
+ }
- int getOrCreateByAddressId(int applicationId, int addressId, long registerTime);
+ @Override public Class[] services() {
+ return new Class[0];
+ }
}
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-define/src/main/resources/META-INF/services/org.apache.skywalking.apm.collector.core.module.ModuleDefine b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-define/src/main/resources/META-INF/services/org.apache.skywalking.apm.collector.core.module.ModuleDefine
new file mode 100644
index 0000000..c8608bc
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-define/src/main/resources/META-INF/services/org.apache.skywalking.apm.collector.core.module.ModuleDefine
@@ -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.apm.collector.receiver.zipkin.define.ZipkinReceiverModule
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/pom.xml b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/pom.xml
new file mode 100644
index 0000000..816a14b
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/pom.xml
@@ -0,0 +1,68 @@
+<?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>receiver-zipkin</artifactId>
+ <groupId>org.apache.skywalking</groupId>
+ <version>5.0.0-beta2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>receiver-zipkin-provider</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.skywalking</groupId>
+ <artifactId>receiver-zipkin-define</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.skywalking</groupId>
+ <artifactId>collector-jetty-manager-define</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.skywalking</groupId>
+ <artifactId>segment-parser-define</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.skywalking</groupId>
+ <artifactId>register-define</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.skywalking</groupId>
+ <artifactId>metric-define</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.github.ben-manes.caffeine</groupId>
+ <artifactId>caffeine</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.zipkin.zipkin2</groupId>
+ <artifactId>zipkin</artifactId>
+ </dependency>
+ </dependencies>
+
+
+</project>
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/Receiver2AnalysisBridge.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/Receiver2AnalysisBridge.java
new file mode 100644
index 0000000..5ef1036
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/Receiver2AnalysisBridge.java
@@ -0,0 +1,48 @@
+/*
+ * 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.apm.collector.receiver.zipkin.provider;
+
+import org.apache.skywalking.apm.collector.analysis.segment.parser.define.service.ISegmentParseService;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.data.SkyWalkingTrace;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.transform.SegmentListener;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.transform.Zipkin2SkyWalkingTransfer;
+
+/**
+ * Send the segments to Analysis module, like receiving segments from native SkyWalking agents.
+ */
+public class Receiver2AnalysisBridge implements SegmentListener {
+ private ISegmentParseService segmentParseService;
+
+ public Receiver2AnalysisBridge(ISegmentParseService segmentParseService) {
+ this.segmentParseService = segmentParseService;
+ }
+
+ /**
+ * Add this bridge as listener to Zipkin span transfer.
+ */
+ public void build() {
+ Zipkin2SkyWalkingTransfer.INSTANCE.addListener(this);
+ }
+
+ @Override
+ public void notify(SkyWalkingTrace trace) {
+ trace.toUpstreamSegment().forEach(upstream -> segmentParseService.parse(upstream.build(), ISegmentParseService.Source.Agent));
+
+ }
+}
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/RegisterServices.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/RegisterServices.java
new file mode 100644
index 0000000..0d3fcc8
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/RegisterServices.java
@@ -0,0 +1,78 @@
+/*
+ * 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.apm.collector.receiver.zipkin.provider;
+
+import org.apache.skywalking.apm.collector.analysis.register.define.service.AgentOsInfo;
+import org.apache.skywalking.apm.collector.analysis.register.define.service.IApplicationIDService;
+import org.apache.skywalking.apm.collector.analysis.register.define.service.IInstanceIDService;
+import org.apache.skywalking.apm.collector.analysis.register.define.service.INetworkAddressIDService;
+import org.apache.skywalking.apm.collector.analysis.register.define.service.IServiceNameService;
+
+/**
+ * @author wusheng
+ */
+public class RegisterServices {
+ private IApplicationIDService applicationIDService;
+
+ private IInstanceIDService instanceIDService;
+
+ private INetworkAddressIDService networkAddressIDService;
+
+ private IServiceNameService serviceNameService;
+
+ public RegisterServices(
+ IApplicationIDService applicationIDService,
+ IInstanceIDService instanceIDService,
+ INetworkAddressIDService networkAddressIDService,
+ IServiceNameService serviceNameService) {
+ this.applicationIDService = applicationIDService;
+ this.instanceIDService = instanceIDService;
+ this.networkAddressIDService = networkAddressIDService;
+ this.serviceNameService = serviceNameService;
+ }
+
+ public IApplicationIDService getApplicationIDService() {
+ return applicationIDService;
+ }
+
+ public IInstanceIDService getInstanceIDService() {
+ return instanceIDService;
+ }
+
+ public INetworkAddressIDService getNetworkAddressIDService() {
+ return networkAddressIDService;
+ }
+
+ public IServiceNameService getServiceNameService() {
+ return serviceNameService;
+ }
+
+ /**
+ * @param applicationId
+ * @param agentUUID in zipkin translation, always means application code. Because no UUID for each process.
+ * @return
+ */
+ public int getOrCreateApplicationInstanceId(int applicationId, String agentUUID) {
+ AgentOsInfo agentOsInfo = new AgentOsInfo();
+ agentOsInfo.setHostname("N/A");
+ agentOsInfo.setOsName("N/A");
+ agentOsInfo.setProcessNo(-1);
+ return getInstanceIDService().getOrCreateByAgentUUID(applicationId, agentUUID, System.currentTimeMillis(), agentOsInfo);
+ }
+}
diff --git a/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverConfig.java
similarity index 56%
copy from apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java
copy to apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverConfig.java
index ed84f05..6e261e9 100644
--- a/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverConfig.java
@@ -16,15 +16,31 @@
*
*/
-package org.apache.skywalking.apm.collector.analysis.register.define.service;
+package org.apache.skywalking.apm.collector.receiver.zipkin.provider;
-import org.apache.skywalking.apm.collector.core.module.Service;
+import org.apache.skywalking.apm.collector.server.jetty.JettyServerConfig;
/**
- * @author peng-yongsheng
+ * @author wusheng
*/
-public interface IInstanceIDService extends Service {
- int getOrCreateByAgentUUID(int applicationId, String agentUUID, long registerTime, String osInfo);
+public class ZipkinReceiverConfig extends JettyServerConfig {
+ private int expireTime = 20;
- int getOrCreateByAddressId(int applicationId, int addressId, long registerTime);
+ private int maxCacheSize = 1_000_000;
+
+ public int getExpireTime() {
+ return expireTime;
+ }
+
+ public void setExpireTime(int expireTime) {
+ this.expireTime = expireTime;
+ }
+
+ public int getMaxCacheSize() {
+ return maxCacheSize;
+ }
+
+ public void setMaxCacheSize(int maxCacheSize) {
+ this.maxCacheSize = maxCacheSize;
+ }
}
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverProvider.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverProvider.java
new file mode 100644
index 0000000..fd364f4
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverProvider.java
@@ -0,0 +1,91 @@
+/*
+ * 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.apm.collector.receiver.zipkin.provider;
+
+import org.apache.skywalking.apm.collector.analysis.metric.define.AnalysisMetricModule;
+import org.apache.skywalking.apm.collector.analysis.metric.define.service.IInstanceHeartBeatService;
+import org.apache.skywalking.apm.collector.analysis.register.define.AnalysisRegisterModule;
+import org.apache.skywalking.apm.collector.analysis.register.define.service.IApplicationIDService;
+import org.apache.skywalking.apm.collector.analysis.register.define.service.IInstanceIDService;
+import org.apache.skywalking.apm.collector.analysis.register.define.service.INetworkAddressIDService;
+import org.apache.skywalking.apm.collector.analysis.register.define.service.IServiceNameService;
+import org.apache.skywalking.apm.collector.analysis.segment.parser.define.AnalysisSegmentParserModule;
+import org.apache.skywalking.apm.collector.analysis.segment.parser.define.service.ISegmentParseService;
+import org.apache.skywalking.apm.collector.core.module.*;
+import org.apache.skywalking.apm.collector.jetty.manager.JettyManagerModule;
+import org.apache.skywalking.apm.collector.jetty.manager.service.JettyManagerService;
+import org.apache.skywalking.apm.collector.receiver.zipkin.define.ZipkinReceiverModule;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.handler.SpanV2JettyHandler;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.transform.Zipkin2SkyWalkingTransfer;
+import org.apache.skywalking.apm.collector.server.jetty.JettyServer;
+
+/**
+ * @author wusheng
+ */
+public class ZipkinReceiverProvider extends ModuleProvider {
+ public static final String NAME = "default";
+ private ZipkinReceiverConfig config;
+
+ public ZipkinReceiverProvider() {
+ config = new ZipkinReceiverConfig();
+ }
+
+ @Override public String name() {
+ return NAME;
+ }
+
+ @Override public Class<? extends ModuleDefine> module() {
+ return ZipkinReceiverModule.class;
+ }
+
+ @Override public ModuleConfig createConfigBeanIfAbsent() {
+ return config;
+ }
+
+ @Override public void prepare() throws ServiceNotProvidedException {
+
+ }
+
+ @Override public void start() throws ServiceNotProvidedException, ModuleStartException {
+ ModuleDefine moduleDefine = getManager().find(AnalysisRegisterModule.NAME);
+ RegisterServices registerServices = new RegisterServices(moduleDefine.getService(IApplicationIDService.class),
+ moduleDefine.getService(IInstanceIDService.class),
+ moduleDefine.getService(INetworkAddressIDService.class),
+ moduleDefine.getService(IServiceNameService.class));
+ IInstanceHeartBeatService instanceHeartBeatService = getManager().find(AnalysisMetricModule.NAME).getService(IInstanceHeartBeatService.class);
+ Zipkin2SkyWalkingTransfer.INSTANCE.setRegisterServices(registerServices);
+ Zipkin2SkyWalkingTransfer.INSTANCE.setInstanceHeartBeatService(instanceHeartBeatService);
+
+ JettyManagerService managerService = getManager().find(JettyManagerModule.NAME).getService(JettyManagerService.class);
+ JettyServer jettyServer = managerService.createIfAbsent(config.getHost(), config.getPort(), config.getContextPath());
+ jettyServer.addHandler(new SpanV2JettyHandler(config, registerServices));
+
+ ISegmentParseService segmentParseService = getManager().find(AnalysisSegmentParserModule.NAME).getService(ISegmentParseService.class);
+ Receiver2AnalysisBridge bridge = new Receiver2AnalysisBridge(segmentParseService);
+ Zipkin2SkyWalkingTransfer.INSTANCE.addListener(bridge);
+ }
+
+ @Override public void notifyAfterCompleted() throws ServiceNotProvidedException {
+
+ }
+
+ @Override public String[] requiredModules() {
+ return new String[] {JettyManagerModule.NAME, AnalysisSegmentParserModule.NAME, AnalysisMetricModule.NAME};
+ }
+}
diff --git a/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/cache/CacheFactory.java
similarity index 51%
copy from apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java
copy to apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/cache/CacheFactory.java
index ed84f05..450f82c 100644
--- a/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/cache/CacheFactory.java
@@ -16,15 +16,30 @@
*
*/
-package org.apache.skywalking.apm.collector.analysis.register.define.service;
+package org.apache.skywalking.apm.collector.receiver.zipkin.provider.cache;
-import org.apache.skywalking.apm.collector.core.module.Service;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.ZipkinReceiverConfig;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.cache.caffeine.CaffeineSpanCache;
/**
- * @author peng-yongsheng
+ * @author wusheng
*/
-public interface IInstanceIDService extends Service {
- int getOrCreateByAgentUUID(int applicationId, String agentUUID, long registerTime, String osInfo);
+public class CacheFactory {
+ public static final CacheFactory INSTANCE = new CacheFactory();
- int getOrCreateByAddressId(int applicationId, int addressId, long registerTime);
+ private ISpanCache implementor;
+
+ private CacheFactory() {
+ }
+
+ public ISpanCache get(ZipkinReceiverConfig config) {
+ if (implementor == null) {
+ synchronized (INSTANCE) {
+ if (implementor == null) {
+ implementor = new CaffeineSpanCache(config);
+ }
+ }
+ }
+ return implementor;
+ }
}
diff --git a/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/cache/ISpanCache.java
similarity index 66%
copy from apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java
copy to apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/cache/ISpanCache.java
index ed84f05..2af5afc 100644
--- a/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/cache/ISpanCache.java
@@ -16,15 +16,13 @@
*
*/
-package org.apache.skywalking.apm.collector.analysis.register.define.service;
+package org.apache.skywalking.apm.collector.receiver.zipkin.provider.cache;
-import org.apache.skywalking.apm.collector.core.module.Service;
+import zipkin2.Span;
/**
- * @author peng-yongsheng
+ * @author wusheng
*/
-public interface IInstanceIDService extends Service {
- int getOrCreateByAgentUUID(int applicationId, String agentUUID, long registerTime, String osInfo);
-
- int getOrCreateByAddressId(int applicationId, int addressId, long registerTime);
+public interface ISpanCache {
+ void addSpan(Span span);
}
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/cache/caffeine/CaffeineSpanCache.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/cache/caffeine/CaffeineSpanCache.java
new file mode 100644
index 0000000..06a9a01
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/cache/caffeine/CaffeineSpanCache.java
@@ -0,0 +1,99 @@
+/*
+ * 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.apm.collector.receiver.zipkin.provider.cache.caffeine;
+
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
+import com.github.benmanes.caffeine.cache.RemovalCause;
+import com.github.benmanes.caffeine.cache.RemovalListener;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.ZipkinReceiverConfig;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.cache.ISpanCache;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.data.ZipkinTrace;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.transform.Zipkin2SkyWalkingTransfer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import zipkin2.Span;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * NOTICE: FROM my test, Caffeine cache triggers/checks expire only face write/read op.
+ * In order to make trace finish in time, I have to set a timer to write a meaningless trace, for active expire.
+ *
+ * @author wusheng
+ */
+public class CaffeineSpanCache implements ISpanCache, RemovalListener<String, ZipkinTrace> {
+ private static final Logger logger = LoggerFactory.getLogger(CaffeineSpanCache.class);
+ private Cache<String, ZipkinTrace> inProcessSpanCache;
+ private ReentrantLock newTraceLock;
+
+ public CaffeineSpanCache(ZipkinReceiverConfig config) {
+ newTraceLock = new ReentrantLock();
+ inProcessSpanCache = Caffeine.newBuilder()
+ .expireAfterWrite(config.getExpireTime(), TimeUnit.SECONDS)
+ .maximumSize(config.getMaxCacheSize())
+ .removalListener(this)
+ .build();
+ Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
+ inProcessSpanCache.put("ACTIVE", new ZipkinTrace.TriggerTrace());
+ }, 2, 3, TimeUnit.SECONDS);
+ }
+
+ /**
+ * Zipkin trace finished by the expired rule.
+ *
+ * @param key
+ * @param trace
+ * @param cause
+ */
+ @Override
+ public void onRemoval(@Nullable String key, @Nullable ZipkinTrace trace, @Nonnull RemovalCause cause) {
+ if (trace instanceof ZipkinTrace.TriggerTrace) {
+ return;
+ }
+ try {
+ Zipkin2SkyWalkingTransfer.INSTANCE.transfer(trace);
+ } catch (Exception e) {
+ logger.error(e.getMessage(), e);
+ logger.warn("Zipkin trace:" + trace);
+ }
+ }
+
+ @Override
+ public void addSpan(Span span) {
+ ZipkinTrace trace = inProcessSpanCache.getIfPresent(span.traceId());
+ if (trace == null) {
+ newTraceLock.lock();
+ try {
+ trace = inProcessSpanCache.getIfPresent(span.traceId());
+ if (trace == null) {
+ trace = new ZipkinTrace();
+ inProcessSpanCache.put(span.traceId(), trace);
+ }
+ } finally {
+ newTraceLock.unlock();
+ }
+ }
+ trace.addSpan(span);
+ }
+}
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/data/SkyWalkingTrace.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/data/SkyWalkingTrace.java
new file mode 100644
index 0000000..517bc03
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/data/SkyWalkingTrace.java
@@ -0,0 +1,58 @@
+/*
+ * 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.apm.collector.receiver.zipkin.provider.data;
+
+import org.apache.skywalking.apm.network.proto.TraceSegmentObject;
+import org.apache.skywalking.apm.network.proto.UniqueId;
+import org.apache.skywalking.apm.network.proto.UpstreamSegment;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Each SkyWalkingTrace consists of segments in each application, original from {@link ZipkinTrace}s
+ */
+public class SkyWalkingTrace {
+ private UniqueId globalTraceId;
+ private List<TraceSegmentObject.Builder> segmentList;
+
+ public SkyWalkingTrace(UniqueId globalTraceId, List<TraceSegmentObject.Builder> segmentList) {
+ this.globalTraceId = globalTraceId;
+ this.segmentList = segmentList;
+ }
+
+ public List<UpstreamSegment.Builder> toUpstreamSegment() {
+ List<UpstreamSegment.Builder> newUpstreamList = new LinkedList<>();
+ segmentList.forEach(segment -> {
+ UpstreamSegment.Builder builder = UpstreamSegment.newBuilder();
+ builder.addGlobalTraceIds(globalTraceId);
+ builder.setSegment(segment.build().toByteString());
+ newUpstreamList.add(builder);
+ });
+ return newUpstreamList;
+ }
+
+ public UniqueId getGlobalTraceId() {
+ return globalTraceId;
+ }
+
+ public List<TraceSegmentObject.Builder> getSegmentList() {
+ return segmentList;
+ }
+}
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/data/ZipkinTrace.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/data/ZipkinTrace.java
new file mode 100644
index 0000000..7708453
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/data/ZipkinTrace.java
@@ -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.apm.collector.receiver.zipkin.provider.data;
+
+import zipkin2.Span;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * @author wusheng
+ */
+public class ZipkinTrace {
+ private List<Span> spans;
+ private ReentrantLock spanWriteLock;
+
+ public ZipkinTrace() {
+ spans = new LinkedList<>();
+ spanWriteLock = new ReentrantLock();
+ }
+
+ public void addSpan(Span span) {
+ spanWriteLock.lock();
+ try {
+ spans.add(span);
+ } finally {
+ spanWriteLock.unlock();
+ }
+ }
+
+ public List<Span> getSpans() {
+ return spans;
+ }
+
+ @Override
+ public String toString() {
+ return "ZipkinTrace{" +
+ "spans=" + spans +
+ '}';
+ }
+
+ public static class TriggerTrace extends ZipkinTrace {
+
+
+ }
+}
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/handler/SpanProcessor.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/handler/SpanProcessor.java
new file mode 100644
index 0000000..f791846
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/handler/SpanProcessor.java
@@ -0,0 +1,54 @@
+/*
+ * 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.apm.collector.receiver.zipkin.provider.handler;
+
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.RegisterServices;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.ZipkinReceiverConfig;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.cache.CacheFactory;
+import zipkin2.Span;
+import zipkin2.codec.SpanBytesDecoder;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.util.List;
+
+public class SpanProcessor {
+ void convert(ZipkinReceiverConfig config, SpanBytesDecoder decoder, HttpServletRequest request, RegisterServices registerServices) throws IOException {
+ int len = request.getContentLength();
+ ServletInputStream iii = request.getInputStream();
+ byte[] buffer = new byte[len];
+ iii.read(buffer, 0, len);
+
+ List<Span> spanList = decoder.decodeList(buffer);
+
+ spanList.forEach(span -> {
+ // In Zipkin, the local service name represents the application owner.
+ String applicationCode = span.localServiceName();
+ if (applicationCode != null) {
+ int applicationId = registerServices.getApplicationIDService().getOrCreateForApplicationCode(applicationCode);
+ if (applicationId != 0) {
+ registerServices.getOrCreateApplicationInstanceId(applicationId, applicationCode);
+ }
+ }
+
+ CacheFactory.INSTANCE.get(config).addSpan(span);
+ });
+ }
+}
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/handler/SpanV1JettyHandler.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/handler/SpanV1JettyHandler.java
new file mode 100644
index 0000000..a75c12d
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/handler/SpanV1JettyHandler.java
@@ -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.apm.collector.receiver.zipkin.provider.handler;
+
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.RegisterServices;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.ZipkinReceiverConfig;
+import org.apache.skywalking.apm.collector.server.jetty.JettyHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import zipkin2.codec.SpanBytesDecoder;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class SpanV1JettyHandler extends JettyHandler {
+ private static final Logger logger = LoggerFactory.getLogger(SpanV2JettyHandler.class);
+
+ private ZipkinReceiverConfig config;
+ private RegisterServices registerServices;
+
+ public SpanV1JettyHandler(ZipkinReceiverConfig config,
+ RegisterServices registerServices) {
+ this.config = config;
+ this.registerServices = registerServices;
+ }
+
+ @Override
+ public String pathSpec() {
+ return "/api/v1/spans";
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) {
+ response.setContentType("application/json");
+ response.setCharacterEncoding("utf-8");
+
+ try {
+ String type = request.getHeader("Content-Type");
+
+ SpanBytesDecoder decoder = type != null && type.contains("/x-thrift")
+ ? SpanBytesDecoder.THRIFT
+ : SpanBytesDecoder.JSON_V1;
+
+ SpanProcessor processor = new SpanProcessor();
+ processor.convert(config, decoder, request, registerServices);
+
+ response.setStatus(202);
+ } catch (Exception e) {
+ response.setStatus(500);
+
+ logger.error(e.getMessage(), e);
+ }
+ }
+
+}
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/handler/SpanV2JettyHandler.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/handler/SpanV2JettyHandler.java
new file mode 100644
index 0000000..7e044d4
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/handler/SpanV2JettyHandler.java
@@ -0,0 +1,73 @@
+/*
+ * 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.apm.collector.receiver.zipkin.provider.handler;
+
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.RegisterServices;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.ZipkinReceiverConfig;
+import org.apache.skywalking.apm.collector.server.jetty.JettyHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import zipkin2.codec.SpanBytesDecoder;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author wusheng
+ */
+public class SpanV2JettyHandler extends JettyHandler {
+ private static final Logger logger = LoggerFactory.getLogger(SpanV2JettyHandler.class);
+
+ private ZipkinReceiverConfig config;
+ private RegisterServices registerServices;
+
+ public SpanV2JettyHandler(ZipkinReceiverConfig config,
+ RegisterServices registerServices) {
+ this.config = config;
+ this.registerServices = registerServices;
+ }
+
+ @Override
+ public String pathSpec() {
+ return "/api/v2/spans";
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) {
+ response.setContentType("application/json");
+ response.setCharacterEncoding("utf-8");
+
+ try {
+ String type = request.getHeader("Content-Type");
+
+ SpanBytesDecoder decoder = type != null && type.contains("/x-protobuf")
+ ? SpanBytesDecoder.PROTO3
+ : SpanBytesDecoder.JSON_V2;
+
+ SpanProcessor processor = new SpanProcessor();
+ processor.convert(config, decoder, request, registerServices);
+
+ response.setStatus(202);
+ } catch (Exception e) {
+ response.setStatus(500);
+
+ logger.error(e.getMessage(), e);
+ }
+ }
+}
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/transform/SegmentBuilder.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/transform/SegmentBuilder.java
new file mode 100644
index 0000000..8266eac
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/transform/SegmentBuilder.java
@@ -0,0 +1,477 @@
+/*
+ * 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.apm.collector.receiver.zipkin.provider.transform;
+
+import org.apache.skywalking.apm.collector.analysis.metric.define.service.IInstanceHeartBeatService;
+import org.apache.skywalking.apm.collector.core.util.StringUtils;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.RegisterServices;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.data.SkyWalkingTrace;
+import org.apache.skywalking.apm.network.proto.*;
+import org.eclipse.jetty.util.StringUtil;
+import zipkin2.Endpoint;
+import zipkin2.Span;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * @author wusheng
+ */
+public class SegmentBuilder {
+ private Context context;
+ private LinkedList<Segment> segments;
+ private Map<String, ClientSideSpan> clientPartSpan;
+
+ private SegmentBuilder() {
+ segments = new LinkedList<>();
+ context = new Context();
+ clientPartSpan = new HashMap<>();
+ }
+
+ public static SkyWalkingTrace build(List<Span> traceSpans,
+ RegisterServices registerServices,
+ IInstanceHeartBeatService instanceHeartBeatService) throws Exception {
+ SegmentBuilder builder = new SegmentBuilder();
+ // This map groups the spans by their parent id, in order to assist to build tree.
+ // key: parentId
+ // value: span
+ Map<String, List<Span>> childSpanMap = new HashMap<>();
+ AtomicReference<Span> root = new AtomicReference<>();
+ traceSpans.forEach(span -> {
+ if (span.parentId() == null) {
+ root.set(span);
+ }
+ List<Span> spanList = childSpanMap.get(span.parentId());
+ if (spanList == null) {
+ spanList = new LinkedList<>();
+ spanList.add(span);
+ childSpanMap.put(span.parentId(), spanList);
+ } else {
+ spanList.add(span);
+ }
+ });
+
+ Span rootSpan = root.get();
+ if (rootSpan != null) {
+ String applicationCode = rootSpan.localServiceName();
+ // If root span doesn't include applicationCode, a.k.a local service name,
+ // Segment can't be built
+ // Ignore the whole trace.
+ // :P Hope anyone could provide better solution.
+ // Wu Sheng.
+ if (StringUtils.isNotEmpty(applicationCode)) {
+ builder.context.addApp(applicationCode, registerServices);
+
+ SpanObject.Builder rootSpanBuilder = builder.initSpan(null, null, rootSpan, true);
+ builder.context.currentSegment().addSpan(rootSpanBuilder);
+ builder.scanSpansFromRoot(rootSpanBuilder, rootSpan, childSpanMap, registerServices);
+
+ builder.segments.add(builder.context.removeApp());
+ }
+ }
+
+ List<TraceSegmentObject.Builder> segmentBuilders = new LinkedList<>();
+ builder.segments.forEach(segment -> {
+ TraceSegmentObject.Builder traceSegmentBuilder = segment.freeze();
+ segmentBuilders.add(traceSegmentBuilder);
+ instanceHeartBeatService.heartBeat(traceSegmentBuilder.getApplicationInstanceId(), segment.getEndTime());
+ });
+ return new SkyWalkingTrace(builder.generateTraceOrSegmentId(), segmentBuilders);
+ }
+
+ private void scanSpansFromRoot(SpanObject.Builder parentSegmentSpan, Span parent,
+ Map<String, List<Span>> childSpanMap,
+ RegisterServices registerServices) throws Exception {
+ String parentId = parent.id();
+ // get child spans by parent span id
+ List<Span> spanList = childSpanMap.get(parentId);
+ if (spanList == null) {
+ return;
+ }
+ for (Span childSpan : spanList) {
+ String localServiceName = childSpan.localServiceName();
+ boolean isNewApp = false;
+ if (StringUtil.isNotBlank(localServiceName)) {
+ if (context.isAppChanged(localServiceName)) {
+ isNewApp = true;
+ }
+ }
+
+ try {
+ if (isNewApp) {
+ context.addApp(localServiceName, registerServices);
+ }
+ SpanObject.Builder childSpanBuilder = initSpan(parentSegmentSpan, parent, childSpan, isNewApp);
+
+ context.currentSegment().addSpan(childSpanBuilder);
+ scanSpansFromRoot(childSpanBuilder, childSpan, childSpanMap, registerServices);
+
+ } finally {
+ if (isNewApp) {
+ segments.add(context.removeApp());
+ }
+ }
+ }
+ }
+
+ private SpanObject.Builder initSpan(SpanObject.Builder parentSegmentSpan, Span parentSpan, Span span,
+ boolean isSegmentRoot) {
+ SpanObject.Builder spanBuilder = SpanObject.newBuilder();
+ spanBuilder.setSpanId(context.currentIDs().nextSpanId());
+ if (isSegmentRoot) {
+ // spanId = -1, means no parent span
+ // spanId is considered unique, and from a positive sequence in each segment.
+ spanBuilder.setParentSpanId(-1);
+ }
+ if (!isSegmentRoot && parentSegmentSpan != null) {
+ spanBuilder.setParentSpanId(parentSegmentSpan.getSpanId());
+ }
+ Span.Kind kind = span.kind();
+ spanBuilder.setOperationName(span.name());
+ ClientSideSpan clientSideSpan;
+ switch (kind) {
+ case CLIENT:
+ spanBuilder.setSpanType(SpanType.Exit);
+ String peer = endpoint2Peer(span.remoteEndpoint());
+ if (peer != null) {
+ spanBuilder.setPeer(peer);
+ }
+ clientSideSpan = new ClientSideSpan(span, spanBuilder);
+ clientPartSpan.put(span.id(), clientSideSpan);
+ break;
+ case SERVER:
+ spanBuilder.setSpanType(SpanType.Entry);
+ this.buildRef(spanBuilder, span, parentSegmentSpan, parentSpan);
+ break;
+ case CONSUMER:
+ spanBuilder.setSpanType(SpanType.Entry);
+ this.buildRef(spanBuilder, span, parentSegmentSpan, parentSpan);
+ break;
+ case PRODUCER:
+ spanBuilder.setSpanType(SpanType.Exit);
+ peer = endpoint2Peer(span.remoteEndpoint());
+ if (peer != null) {
+ spanBuilder.setPeer(peer);
+ }
+ clientSideSpan = new ClientSideSpan(span, spanBuilder);
+ clientPartSpan.put(span.id(), clientSideSpan);
+ break;
+ default:
+ spanBuilder.setSpanType(SpanType.Local);
+ }
+ // microseconds in Zipkin -> milliseconds in SkyWalking
+ long startTime = span.timestamp() / 1000;
+ long duration = span.duration() / 1000;
+ spanBuilder.setStartTime(startTime);
+ spanBuilder.setEndTime(startTime + duration);
+
+ span.tags().forEach((tagKey, tagValue) -> spanBuilder.addTags(
+ KeyWithStringValue.newBuilder().setKey(tagKey).setValue(tagValue).build())
+ );
+
+ span.annotations().forEach(annotation ->
+ spanBuilder.addLogs(LogMessage.newBuilder().setTime(annotation.timestamp() / 1000).addData(
+ KeyWithStringValue.newBuilder().setKey("zipkin.annotation").setValue(annotation.value()).build()
+ ))
+ );
+
+ return spanBuilder;
+ }
+
+ private String endpoint2Peer(Endpoint endpoint) {
+ if (endpoint == null) {
+ return null;
+ }
+ String ip = null;
+ if (StringUtils.isNotEmpty(endpoint.ipv4())) {
+ ip = endpoint.ipv4();
+ } else if (StringUtils.isNotEmpty(endpoint.ipv6())) {
+ ip = endpoint.ipv6();
+ }
+ if (StringUtils.isEmpty(ip)) {
+ return null;
+ }
+ int port = endpoint.port();
+ return port == 0 ? ip : ip + ":" + port;
+ }
+
+ private void buildRef(SpanObject.Builder spanBuilder, Span span, SpanObject.Builder parentSegmentSpan,
+ Span parentSpan) {
+ Segment parentSegment = context.parentSegment();
+ if (parentSegment == null) {
+ return;
+ }
+ Segment rootSegment = context.rootSegment();
+ if (rootSegment == null) {
+ return;
+ }
+
+ if (span.shared() != null && span.shared()) {
+ // using same span id in client and server for RPC
+ // SkyWalking will build both sides of span
+ ClientSideSpan clientSideSpan = clientPartSpan.get(span.id());
+ parentSegmentSpan = clientSideSpan.getBuilder();
+ parentSpan = clientSideSpan.getSpan();
+ }
+
+ String ip = null;
+ int port = 0;
+ Endpoint serverEndpoint = span.localEndpoint();
+ Endpoint clientEndpoint = parentSpan.remoteEndpoint();
+ if (clientEndpoint != null) {
+ if (StringUtil.isBlank(ip)) {
+ if (StringUtils.isNotEmpty(clientEndpoint.ipv4())) {
+ ip = clientEndpoint.ipv4();
+ } else if (StringUtils.isNotEmpty(clientEndpoint.ipv6())) {
+ ip = clientEndpoint.ipv6();
+ }
+ port = clientEndpoint.port();
+ }
+ }
+ if (serverEndpoint != null) {
+ if (StringUtils.isNotEmpty(serverEndpoint.ipv4())) {
+ ip = serverEndpoint.ipv4();
+ } else if (StringUtils.isNotEmpty(serverEndpoint.ipv6())) {
+ ip = serverEndpoint.ipv6();
+ }
+ }
+
+ if (StringUtil.isBlank(ip)) {
+ //The IP is the most important for building the ref at both sides.
+ return;
+ }
+
+ TraceSegmentReference.Builder refBuilder = TraceSegmentReference.newBuilder();
+ refBuilder.setEntryApplicationInstanceId(rootSegment.builder().getApplicationInstanceId());
+ int serviceId = rootSegment.getEntryServiceId();
+ if (serviceId == 0) {
+ refBuilder.setEntryServiceName(rootSegment.getEntryServiceName());
+ } else {
+ refBuilder.setEntryServiceId(serviceId);
+ }
+ refBuilder.setEntryApplicationInstanceId(rootSegment.builder().getApplicationInstanceId());
+
+ // parent ref info
+ refBuilder.setNetworkAddress(port == 0 ? ip : ip + ":" + port);
+ parentSegmentSpan.setPeer(refBuilder.getNetworkAddress());
+ refBuilder.setParentApplicationInstanceId(parentSegment.builder().getApplicationInstanceId());
+ refBuilder.setParentSpanId(parentSegmentSpan.getSpanId());
+ refBuilder.setParentTraceSegmentId(parentSegment.builder().getTraceSegmentId());
+ int parentServiceId = parentSegment.getEntryServiceId();
+ if (parentServiceId == 0) {
+ refBuilder.setParentServiceName(parentSegment.getEntryServiceName());
+ } else {
+ refBuilder.setParentServiceId(parentServiceId);
+ }
+ refBuilder.setRefType(RefType.CrossProcess);
+
+ spanBuilder.addRefs(refBuilder);
+ }
+
+ /**
+ * Context holds the values in build process.
+ */
+ private class Context {
+ private LinkedList<Segment> segmentsStack = new LinkedList<>();
+
+ private boolean isAppChanged(String applicationCode) {
+ return StringUtils.isNotEmpty(applicationCode) && !applicationCode.equals(currentIDs().applicationCode);
+ }
+
+ private Segment addApp(String applicationCode,
+ RegisterServices registerServices) throws Exception {
+ int applicationId = waitForExchange(() ->
+ registerServices.getApplicationIDService().getOrCreateForApplicationCode(applicationCode),
+ 10
+ );
+
+ int appInstanceId = waitForExchange(() ->
+ registerServices.getOrCreateApplicationInstanceId(applicationId, applicationCode),
+ 10
+ );
+
+ Segment segment = new Segment(applicationCode, applicationId, appInstanceId);
+ segmentsStack.add(segment);
+ return segment;
+ }
+
+ private IDCollection currentIDs() {
+ return segmentsStack.getLast().ids;
+ }
+
+ private Segment currentSegment() {
+ return segmentsStack.getLast();
+ }
+
+ private Segment parentSegment() {
+ if (segmentsStack.size() < 2) {
+ return null;
+ } else {
+ return segmentsStack.get(segmentsStack.size() - 2);
+ }
+
+ }
+
+ private Segment rootSegment() {
+ if (segmentsStack.size() < 2) {
+ return null;
+ } else {
+ return segmentsStack.getFirst();
+ }
+ }
+
+ private Segment removeApp() {
+ return segmentsStack.removeLast();
+ }
+
+ private int waitForExchange(Callable<Integer> callable, int retry) throws Exception {
+ for (int i = 0; i < retry; i++) {
+ Integer id = callable.call();
+ if (id == 0) {
+ Thread.sleep(1000L);
+ } else {
+ return id;
+ }
+ }
+ throw new TimeoutException("ID exchange costs more than expected.");
+ }
+ }
+
+ private class Segment {
+ private TraceSegmentObject.Builder segmentBuilder;
+ private IDCollection ids;
+ private int entryServiceId = 0;
+ private String entryServiceName = null;
+ private List<SpanObject.Builder> spans;
+ private long endTime = 0;
+
+ private Segment(String applicationCode, int applicationId, int appInstanceId) {
+ ids = new IDCollection(applicationCode, applicationId, appInstanceId);
+ spans = new LinkedList<>();
+ segmentBuilder = TraceSegmentObject.newBuilder();
+ segmentBuilder.setApplicationId(applicationId);
+ segmentBuilder.setApplicationInstanceId(appInstanceId);
+ segmentBuilder.setTraceSegmentId(generateTraceOrSegmentId());
+ }
+
+ private TraceSegmentObject.Builder builder() {
+ return segmentBuilder;
+ }
+
+ private void addSpan(SpanObject.Builder spanBuilder) {
+ String operationName = spanBuilder.getOperationName();
+ if (entryServiceId == 0 && StringUtils.isNotEmpty(operationName)) {
+ if (SpanType.Entry == spanBuilder.getSpanType()) {
+ if (StringUtils.isNotEmpty(operationName)) {
+ entryServiceName = operationName;
+ } else {
+ entryServiceId = spanBuilder.getOperationNameId();
+ }
+ }
+ }
+
+ // init by root span
+ if (spanBuilder.getSpanId() == 1 && entryServiceId == 0) {
+ if (StringUtils.isNotEmpty(operationName)) {
+ entryServiceName = operationName;
+ } else {
+ entryServiceId = spanBuilder.getOperationNameId();
+ }
+ }
+
+ spans.add(spanBuilder);
+ if (spanBuilder.getEndTime() > endTime) {
+ endTime = spanBuilder.getEndTime();
+ }
+ }
+
+ public int getEntryServiceId() {
+ return entryServiceId;
+ }
+
+ public String getEntryServiceName() {
+ return entryServiceName;
+ }
+
+ private IDCollection ids() {
+ return ids;
+ }
+
+ public TraceSegmentObject.Builder freeze() {
+ for (SpanObject.Builder span : spans) {
+ segmentBuilder.addSpans(span);
+ }
+ return segmentBuilder;
+ }
+
+ public long getEndTime() {
+ return endTime;
+ }
+ }
+
+ private class IDCollection {
+ private String applicationCode;
+ private int appId;
+ private int instanceId;
+ private int spanIdSeq;
+
+ private IDCollection(String applicationCode, int appId, int instanceId) {
+ this.applicationCode = applicationCode;
+ this.appId = appId;
+ this.instanceId = instanceId;
+ this.spanIdSeq = 0;
+ }
+
+ private int nextSpanId() {
+ return spanIdSeq++;
+ }
+ }
+
+ private UniqueId generateTraceOrSegmentId() {
+ return UniqueId.newBuilder()
+ .addIdParts(ThreadLocalRandom.current().nextLong())
+ .addIdParts(ThreadLocalRandom.current().nextLong())
+ .addIdParts(ThreadLocalRandom.current().nextLong())
+ .build();
+ }
+
+ private class ClientSideSpan {
+ private Span span;
+ private SpanObject.Builder builder;
+
+ public ClientSideSpan(Span span, SpanObject.Builder builder) {
+ this.span = span;
+ this.builder = builder;
+ }
+
+ public Span getSpan() {
+ return span;
+ }
+
+ public SpanObject.Builder getBuilder() {
+ return builder;
+ }
+ }
+}
diff --git a/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/transform/SegmentListener.java
similarity index 65%
copy from apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java
copy to apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/transform/SegmentListener.java
index ed84f05..72623e0 100644
--- a/apm-collector/apm-collector-analysis/analysis-register/register-define/src/main/java/org/apache/skywalking/apm/collector/analysis/register/define/service/IInstanceIDService.java
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/transform/SegmentListener.java
@@ -16,15 +16,10 @@
*
*/
-package org.apache.skywalking.apm.collector.analysis.register.define.service;
+package org.apache.skywalking.apm.collector.receiver.zipkin.provider.transform;
-import org.apache.skywalking.apm.collector.core.module.Service;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.data.SkyWalkingTrace;
-/**
- * @author peng-yongsheng
- */
-public interface IInstanceIDService extends Service {
- int getOrCreateByAgentUUID(int applicationId, String agentUUID, long registerTime, String osInfo);
-
- int getOrCreateByAddressId(int applicationId, int addressId, long registerTime);
+public interface SegmentListener {
+ void notify(SkyWalkingTrace trace);
}
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/transform/Zipkin2SkyWalkingTransfer.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/transform/Zipkin2SkyWalkingTransfer.java
new file mode 100644
index 0000000..174903b
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/transform/Zipkin2SkyWalkingTransfer.java
@@ -0,0 +1,67 @@
+/*
+ * 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.apm.collector.receiver.zipkin.provider.transform;
+
+import org.apache.skywalking.apm.collector.analysis.metric.define.service.IInstanceHeartBeatService;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.RegisterServices;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.data.SkyWalkingTrace;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.data.ZipkinTrace;
+import zipkin2.Span;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author wusheng
+ */
+public class Zipkin2SkyWalkingTransfer {
+ public static Zipkin2SkyWalkingTransfer INSTANCE = new Zipkin2SkyWalkingTransfer();
+ private RegisterServices registerServices;
+ private IInstanceHeartBeatService instanceHeartBeatService;
+ private List<SegmentListener> listeners = new LinkedList<>();
+
+ private Zipkin2SkyWalkingTransfer() {
+ }
+
+ public void setRegisterServices(
+ RegisterServices registerServices) {
+ this.registerServices = registerServices;
+ }
+
+ public void setInstanceHeartBeatService(IInstanceHeartBeatService instanceHeartBeatService) {
+ this.instanceHeartBeatService = instanceHeartBeatService;
+ }
+
+ public void addListener(SegmentListener listener) {
+ listeners.add(listener);
+ }
+
+ public void transfer(ZipkinTrace trace) throws Exception {
+ List<Span> traceSpans = trace.getSpans();
+
+ if (traceSpans.size() > 0) {
+ SkyWalkingTrace skyWalkingTrace = SegmentBuilder.build(traceSpans, registerServices, instanceHeartBeatService);
+
+ listeners.forEach(listener ->
+ listener.notify(skyWalkingTrace)
+ );
+
+ }
+ }
+}
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/resources/META-INF/services/org.apache.skywalking.apm.collector.core.module.ModuleProvider b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/resources/META-INF/services/org.apache.skywalking.apm.collector.core.module.ModuleProvider
new file mode 100644
index 0000000..9046f75
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/resources/META-INF/services/org.apache.skywalking.apm.collector.core.module.ModuleProvider
@@ -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.apm.collector.receiver.zipkin.provider.ZipkinReceiverProvider
diff --git a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/test/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/transform/SpringSleuthSegmentBuilderTest.java b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/test/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/transform/SpringSleuthSegmentBuilderTest.java
new file mode 100644
index 0000000..8a5e1c7
--- /dev/null
+++ b/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/test/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/transform/SpringSleuthSegmentBuilderTest.java
@@ -0,0 +1,196 @@
+/*
+ * 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.apm.collector.receiver.zipkin.provider.transform;
+
+import org.apache.skywalking.apm.collector.analysis.metric.define.service.IInstanceHeartBeatService;
+import org.apache.skywalking.apm.collector.analysis.register.define.service.AgentOsInfo;
+import org.apache.skywalking.apm.collector.analysis.register.define.service.IApplicationIDService;
+import org.apache.skywalking.apm.collector.analysis.register.define.service.IInstanceIDService;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.RegisterServices;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.data.SkyWalkingTrace;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.data.ZipkinTrace;
+import org.apache.skywalking.apm.network.proto.SpanObject;
+import org.apache.skywalking.apm.network.proto.SpanType;
+import org.apache.skywalking.apm.network.proto.TraceSegmentObject;
+import org.apache.skywalking.apm.network.proto.TraceSegmentReference;
+import org.junit.Assert;
+import org.junit.Test;
+import zipkin2.Span;
+import zipkin2.codec.SpanBytesDecoder;
+
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author wusheng
+ */
+public class SpringSleuthSegmentBuilderTest implements SegmentListener {
+ private Map<String, Integer> applicationInstRegister = new HashMap<>();
+ private Map<String, Integer> applicationRegister = new HashMap<>();
+ private int appIdSeg = 1;
+ private int appInstIdSeq = 1;
+
+ @Test
+ public void testTransform() throws Exception {
+
+ IApplicationIDService applicationIDService = new IApplicationIDService() {
+ @Override
+ public int getOrCreateForApplicationCode(String applicationCode) {
+ String key = "AppCode:" + applicationCode;
+ if (applicationRegister.containsKey(key)) {
+ return applicationRegister.get(key);
+ } else {
+ int id = appIdSeg++;
+ applicationRegister.put(key, id);
+ return id;
+ }
+ }
+
+ @Override
+ public int getOrCreateForAddressId(int addressId, String networkAddress) {
+ String key = "Address:" + networkAddress;
+ if (applicationRegister.containsKey(key)) {
+ return applicationRegister.get(key);
+ } else {
+ int id = appIdSeg++;
+ applicationRegister.put(key, id);
+ return id;
+ }
+ }
+ };
+
+ IInstanceIDService instanceIDService = new IInstanceIDService() {
+ @Override
+ public int getOrCreateByAgentUUID(int applicationId, String agentUUID, long registerTime, AgentOsInfo osInfo) {
+ String key = "AppCode:" + applicationId + ",UUID:" + agentUUID;
+ if (applicationInstRegister.containsKey(key)) {
+ return applicationInstRegister.get(key);
+ } else {
+ int id = appInstIdSeq++;
+ applicationInstRegister.put(key, id);
+ return id;
+ }
+ }
+
+ @Override
+ public int getOrCreateByAddressId(int applicationId, int addressId, long registerTime) {
+ String key = "VitualAppCode:" + applicationId + ",address:" + addressId;
+ if (applicationInstRegister.containsKey(key)) {
+ return applicationInstRegister.get(key);
+ } else {
+ int id = appInstIdSeq++;
+ applicationInstRegister.put(key, id);
+ return id;
+ }
+ }
+ };
+ RegisterServices services = new RegisterServices(applicationIDService, instanceIDService, null, null);
+
+ Zipkin2SkyWalkingTransfer.INSTANCE.addListener(this);
+ Zipkin2SkyWalkingTransfer.INSTANCE.setRegisterServices(services);
+ Zipkin2SkyWalkingTransfer.INSTANCE.setInstanceHeartBeatService(new IInstanceHeartBeatService() {
+ @Override
+ public void heartBeat(int instanceId, long heartBeatTime) {
+
+ }
+ });
+
+ List<Span> spanList = buildSpringSleuthExampleTrace();
+ Assert.assertEquals(3, spanList.size());
+
+ ZipkinTrace trace = new ZipkinTrace();
+ spanList.forEach(span -> trace.addSpan(span));
+
+ Zipkin2SkyWalkingTransfer.INSTANCE.transfer(trace);
+ }
+
+ private List<Span> buildSpringSleuthExampleTrace() throws UnsupportedEncodingException {
+ List<Span> spans = new LinkedList<>();
+ String span = "{\"traceId\":\"5b0e64354eea4fa71a8a1b5bdd791b8a\",\"id\":\"1a8a1b5bdd791b8a\",\"kind\":\"SERVER\",\"name\":\"get /\",\"timestamp\":1527669813700123,\"duration\":11295,\"localEndpoint\":{\"serviceName\":\"frontend\",\"ipv4\":\"192.168.72.220\"},\"remoteEndpoint\":{\"ipv6\":\"::1\",\"port\":55146},\"tags\":{\"http.method\":\"GET\",\"http.path\":\"/\",\"mvc.controller.class\":\"Frontend\",\"mvc.controller.method\":\"callBackend\"}}";
+ spans.add(SpanBytesDecoder.JSON_V2.decodeOne(span.getBytes("UTF-8")));
+ span = "{\"traceId\":\"5b0e64354eea4fa71a8a1b5bdd791b8a\",\"parentId\":\"1a8a1b5bdd791b8a\",\"id\":\"d7d5b93dcda767c8\",\"kind\":\"CLIENT\",\"name\":\"get\",\"timestamp\":1527669813702456,\"duration\":6672,\"localEndpoint\":{\"serviceName\":\"frontend\",\"ipv4\":\"192.168.72.220\"},\"tags\":{\"http.method\":\"GET\",\"http.path\":\"/api\"}}";
+ spans.add(SpanBytesDecoder.JSON_V2.decodeOne(span.getBytes("UTF-8")));
+ span = "{\"traceId\":\"5b0e64354eea4fa71a8a1b5bdd791b8a\",\"parentId\":\"1a8a1b5bdd791b8a\",\"id\":\"d7d5b93dcda767c8\",\"kind\":\"SERVER\",\"name\":\"get /api\",\"timestamp\":1527669813705106,\"duration\":4802,\"localEndpoint\":{\"serviceName\":\"backend\",\"ipv4\":\"192.168.72.220\"},\"remoteEndpoint\":{\"ipv4\":\"127.0.0.1\",\"port\":55147},\"tags\":{\"http.method\":\"GET\",\"http.path\":\"/api\",\"mvc.controller.class\":\"Backend\",\"mvc.controller.method\":\"printDate\"},\"s [...]
+ spans.add(SpanBytesDecoder.JSON_V2.decodeOne(span.getBytes("UTF-8")));
+
+ return SpanBytesDecoder.JSON_V2.decodeList(spans.toString().getBytes("UTF-8"));
+ }
+
+ @Override
+ public void notify(SkyWalkingTrace trace) {
+ List<TraceSegmentObject.Builder> segments = trace.getSegmentList();
+ Assert.assertEquals(2, segments.size());
+ TraceSegmentObject.Builder builder = segments.get(0);
+ TraceSegmentObject.Builder builder1 = segments.get(1);
+ TraceSegmentObject.Builder front, end;
+ if (builder.getApplicationId() == applicationRegister.get("AppCode:frontend")) {
+ front = builder;
+ end = builder1;
+ Assert.assertEquals(applicationRegister.get("AppCode:backend").longValue(), builder1.getApplicationId());
+ } else if (builder.getApplicationId() == applicationRegister.get("AppCode:backend")) {
+ end = builder;
+ front = builder1;
+ Assert.assertEquals(applicationRegister.get("AppCode:frontend").longValue(), builder1.getApplicationId());
+ } else {
+ Assert.fail("Can't find frontend and backend applications. ");
+ return;
+ }
+
+ Assert.assertEquals(2, front.getSpansCount());
+ Assert.assertEquals(1, end.getSpansCount());
+
+ front.getSpansList().forEach(spanObject -> {
+ if (spanObject.getSpanId() == 0) {
+ // span id = 1, means incoming http of frontend
+ Assert.assertEquals(SpanType.Entry, spanObject.getSpanType());
+ Assert.assertEquals("get /", spanObject.getOperationName());
+ Assert.assertEquals(0, spanObject.getSpanId());
+ Assert.assertEquals(-1, spanObject.getParentSpanId());
+ } else if (spanObject.getSpanId() == 1) {
+ Assert.assertEquals("192.168.72.220", spanObject.getPeer());
+ Assert.assertEquals(SpanType.Exit, spanObject.getSpanType());
+ Assert.assertEquals(1, spanObject.getSpanId());
+ Assert.assertEquals(0, spanObject.getParentSpanId());
+ } else {
+ Assert.fail("Only two spans expected");
+ }
+ Assert.assertTrue(spanObject.getTagsCount() > 0);
+ });
+
+ SpanObject spanObject = end.getSpans(0);
+
+ Assert.assertEquals(1, spanObject.getRefsCount());
+ TraceSegmentReference spanObjectRef = spanObject.getRefs(0);
+ Assert.assertEquals("get", spanObjectRef.getEntryServiceName());
+ Assert.assertEquals("get", spanObjectRef.getParentServiceName());
+ //Assert.assertEquals("192.168.72.220", spanObjectRef.getNetworkAddress());
+ Assert.assertEquals(1, spanObjectRef.getParentSpanId());
+ Assert.assertEquals(front.getTraceSegmentId(), spanObjectRef.getParentTraceSegmentId());
+
+ Assert.assertTrue(spanObject.getTagsCount() > 0);
+
+ Assert.assertEquals("get /api", spanObject.getOperationName());
+ Assert.assertEquals(0, spanObject.getSpanId());
+ Assert.assertEquals(-1, spanObject.getParentSpanId());
+ Assert.assertEquals(SpanType.Entry, spanObject.getSpanType());
+ }
+}
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/ui/jetty/handler/GraphQLHandler.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/ui/jetty/handler/GraphQLHandler.java
index ae49a8e..56f36c4 100644
--- a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/ui/jetty/handler/GraphQLHandler.java
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/ui/jetty/handler/GraphQLHandler.java
@@ -39,7 +39,7 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.skywalking.apm.collector.core.module.ModuleManager;
import org.apache.skywalking.apm.collector.core.util.CollectionUtils;
import org.apache.skywalking.apm.collector.server.jetty.ArgumentsParseException;
-import org.apache.skywalking.apm.collector.server.jetty.JettyHandler;
+import org.apache.skywalking.apm.collector.server.jetty.JettyJsonHandler;
import org.apache.skywalking.apm.collector.storage.ui.application.ApplicationNode;
import org.apache.skywalking.apm.collector.storage.ui.application.ConjecturalNode;
import org.apache.skywalking.apm.collector.storage.ui.common.VisualUserNode;
@@ -60,7 +60,7 @@ import org.slf4j.LoggerFactory;
/**
* @author peng-yongsheng
*/
-public class GraphQLHandler extends JettyHandler {
+public class GraphQLHandler extends JettyJsonHandler {
private static final Logger logger = LoggerFactory.getLogger(GraphQLHandler.class);
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/ui/jetty/handler/naming/UIJettyNamingHandler.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/ui/jetty/handler/naming/UIJettyNamingHandler.java
index dc035f8..e9920dd 100644
--- a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/ui/jetty/handler/naming/UIJettyNamingHandler.java
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/main/java/org/apache/skywalking/apm/collector/ui/jetty/handler/naming/UIJettyNamingHandler.java
@@ -24,12 +24,12 @@ import com.google.gson.JsonElement;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.skywalking.apm.collector.server.jetty.ArgumentsParseException;
-import org.apache.skywalking.apm.collector.server.jetty.JettyHandler;
+import org.apache.skywalking.apm.collector.server.jetty.JettyJsonHandler;
/**
* @author peng-yongsheng
*/
-public class UIJettyNamingHandler extends JettyHandler {
+public class UIJettyNamingHandler extends JettyJsonHandler {
private final UIJettyNamingListener namingListener;
diff --git a/apm-collector/pom.xml b/apm-collector/pom.xml
index 56702ac..11beffb 100644
--- a/apm-collector/pom.xml
+++ b/apm-collector/pom.xml
@@ -45,6 +45,7 @@
<module>apm-collector-configuration</module>
<module>apm-collector-agent</module>
<module>apm-collector-analysis</module>
+ <module>apm-collector-thirdparty-receiver</module>
</modules>
<properties>
@@ -63,6 +64,7 @@
<jedis.version>2.9.0</jedis.version>
<zookeeper.version>3.4.10</zookeeper.version>
<elasticsearch.client.version>5.5.0</elasticsearch.client.version>
+ <zipkin.version>2.9.1</zipkin.version>
<shardingjdbc.version>2.0.3</shardingjdbc.version>
<commons-dbcp.version>1.4</commons-dbcp.version>
</properties>
@@ -248,6 +250,11 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>io.zipkin.zipkin2</groupId>
+ <artifactId>zipkin</artifactId>
+ <version>${zipkin.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>
</project>
diff --git a/apm-dist/release-docs/LICENSE b/apm-dist/release-docs/LICENSE
index 8984e46..f0098a6 100644
--- a/apm-dist/release-docs/LICENSE
+++ b/apm-dist/release-docs/LICENSE
@@ -289,6 +289,7 @@ The text of each license is also included at licenses/LICENSE-[project].txt.
validation-api 1.1.0.Final: http://beanvalidation.org/licensing/, Apache 2.0
zuul-core 1.3.0: https://github.com/Netflix/zuul, Apache 2.0
ben-manes caffeine 2.6.2: https://github.com/ben-manes/caffeine, Apache 2.0
+ zipkin 2.9.1: https://github.com/openzipkin/zipkin, Apache 2.0
sharding-jdbc-core 2.0.3: https://github.com/sharding-sphere/sharding-sphere, Apache 2.0
========================================================================
diff --git a/docs/README.md b/docs/README.md
index 09b4e19..bf34c05 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -21,6 +21,7 @@
* Incubating Features
* [Why are some features in **Incubating**?](en/Incubating/Abstract.md)
* [Use Sharding JDBC as storage implementor](en/Use-ShardingJDBC-as-storage-implementor.md)
+ * [Receive Zipkin span data format](../apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/docs/README.md)
* Application Toolkit
* [Overview](en/Applicaton-toolkit.md)
* [Use SkyWalking OpenTracing compatible tracer](en/Opentracing.md)
diff --git a/docs/en/Incubating/Abstract.md b/docs/en/Incubating/Abstract.md
index 452146d..34769d3 100644
--- a/docs/en/Incubating/Abstract.md
+++ b/docs/en/Incubating/Abstract.md
@@ -10,3 +10,4 @@ List some typical incubating features
1. New storage implementor in collector, such as: ElasticSearch HTTP, MySQL...
1. New module provided in collector.
1. New optional plugins in agent.
+1. New features/services in collector, as the integration.
--
To stop receiving notification emails like this one, please contact
wusheng@apache.org.