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/05/28 07:43:52 UTC

[incubator-skywalking] branch zipkin/receiver-v1 updated: Finish zipkin trace cache and finish mechanism(based on timeout)

This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch zipkin/receiver-v1
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git


The following commit(s) were added to refs/heads/zipkin/receiver-v1 by this push:
     new b6e2189  Finish zipkin trace cache and finish mechanism(based on timeout)
b6e2189 is described below

commit b6e21898d192545fc67b0f66a0c359faae0a40d4
Author: wusheng <wu...@foxmail.com>
AuthorDate: Mon May 28 15:43:32 2018 +0800

    Finish zipkin trace cache and finish mechanism(based on timeout)
---
 .../apm/collector/server/jetty/JettyHandler.java   |   4 +-
 .../receiver-zipkin-provider/pom.xml               |   4 +
 .../zipkin/provider/ZipkinReceiverConfig.java      |  19 +++
 .../zipkin/provider/ZipkinReceiverProvider.java    |   2 +-
 .../CacheFactory.java}                             |  31 +++--
 .../ISpanCache.java}                               |   7 +-
 .../provider/cache/caffeine/CaffeineSpanCache.java |  74 ++++++++++
 .../Annotation.java}                               |  25 +++-
 .../SpanJettyHandler.java => data/Endpoint.java}   |  50 +++++--
 .../{ZipkinReceiverConfig.java => data/Kind.java}  |   7 +-
 .../receiver/zipkin/provider/data/ZipkinSpan.java  | 149 +++++++++++++++++++++
 .../ZipkinTrace.java}                              |  24 +++-
 .../zipkin/provider/handler/SpanJettyHandler.java  |  59 +++++++-
 13 files changed, 408 insertions(+), 47 deletions(-)

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..2d5b784 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
@@ -43,7 +43,7 @@ public abstract class JettyHandler extends HttpServlet implements ServerHandler
     public abstract String pathSpec();
 
     @Override
-    protected final void doGet(HttpServletRequest req, HttpServletResponse resp) {
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
         try {
             reply(resp, doGet(req));
         } catch (ArgumentsParseException | IOException e) {
@@ -58,7 +58,7 @@ public abstract class JettyHandler extends HttpServlet implements ServerHandler
     protected abstract JsonElement doGet(HttpServletRequest req) throws ArgumentsParseException;
 
     @Override
-    protected final void doPost(HttpServletRequest req, HttpServletResponse resp) {
+    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
         try {
             reply(resp, doPost(req));
         } catch (ArgumentsParseException | IOException e) {
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
index 0ea71ba..7719a1c 100644
--- 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
@@ -39,6 +39,10 @@
             <artifactId>collector-jetty-manager-define</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>com.github.ben-manes.caffeine</groupId>
+            <artifactId>caffeine</artifactId>
+        </dependency>
     </dependencies>
 
 
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/ZipkinReceiverConfig.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
index 9afe409..936d9c2 100644
--- a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverConfig.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
@@ -24,4 +24,23 @@ import org.apache.skywalking.apm.collector.server.jetty.JettyServerConfig;
  * @author wusheng
  */
 public class ZipkinReceiverConfig extends JettyServerConfig {
+    private int expireTime = 1;
+
+    private int maxCacheTime = 1_000_000;
+
+    public int getExpireTime() {
+        return expireTime;
+    }
+
+    public void setExpireTime(int expireTime) {
+        this.expireTime = expireTime;
+    }
+
+    public int getMaxCacheTime() {
+        return maxCacheTime;
+    }
+
+    public void setMaxCacheTime(int maxCacheTime) {
+        this.maxCacheTime = maxCacheTime;
+    }
 }
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
index 13ae2bf..97029e8 100644
--- 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
@@ -89,6 +89,6 @@ public class ZipkinReceiverProvider extends ModuleProvider {
     }
 
     private void addHandlers(JettyServer jettyServer) {
-        jettyServer.addHandler(new SpanJettyHandler());
+        jettyServer.addHandler(new SpanJettyHandler(config));
     }
 }
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/SpanJettyHandler.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 57%
copy from apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/handler/SpanJettyHandler.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 607a26d..450f82c 100644
--- a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/handler/SpanJettyHandler.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,27 +16,30 @@
  *
  */
 
-package org.apache.skywalking.apm.collector.receiver.zipkin.provider.handler;
+package org.apache.skywalking.apm.collector.receiver.zipkin.provider.cache;
 
-import com.google.gson.JsonElement;
-import java.io.IOException;
-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.receiver.zipkin.provider.ZipkinReceiverConfig;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.cache.caffeine.CaffeineSpanCache;
 
 /**
  * @author wusheng
  */
-public class SpanJettyHandler extends JettyHandler {
-    @Override public String pathSpec() {
-        return "/api/v2/spans";
-    }
+public class CacheFactory {
+    public static final CacheFactory INSTANCE = new CacheFactory();
+
+    private ISpanCache implementor;
 
-    @Override protected JsonElement doGet(HttpServletRequest req) throws ArgumentsParseException {
-        return null;
+    private CacheFactory() {
     }
 
-    @Override protected JsonElement doPost(HttpServletRequest req) throws ArgumentsParseException, IOException {
-        return null;
+    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-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverConfig.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 84%
copy from apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverConfig.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 9afe409..0b46451 100644
--- a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverConfig.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,12 +16,13 @@
  *
  */
 
-package org.apache.skywalking.apm.collector.receiver.zipkin.provider;
+package org.apache.skywalking.apm.collector.receiver.zipkin.provider.cache;
 
-import org.apache.skywalking.apm.collector.server.jetty.JettyServerConfig;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.data.ZipkinSpan;
 
 /**
  * @author wusheng
  */
-public class ZipkinReceiverConfig extends JettyServerConfig {
+public interface ISpanCache {
+    void addSpan(ZipkinSpan 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..bd6f042
--- /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,74 @@
+/*
+ * 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 java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+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.ZipkinSpan;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.data.ZipkinTrace;
+
+/**
+ * @author wusheng
+ */
+public class CaffeineSpanCache implements ISpanCache, RemovalListener<String, ZipkinTrace> {
+    private Cache<String, ZipkinTrace> inProcessSpanCache;
+    private ReentrantLock newTraceLock;
+
+    public CaffeineSpanCache(ZipkinReceiverConfig config) {
+        newTraceLock = new ReentrantLock();
+        inProcessSpanCache = Caffeine.newBuilder()
+            .expireAfterWrite(config.getExpireTime(), TimeUnit.MINUTES)
+            .removalListener(this)
+            .build();
+    }
+
+    /**
+     * Zipkin trace finished by the expired rule.
+     *
+     * @param key
+     * @param value
+     * @param cause
+     */
+    @Override
+    public void onRemoval(@Nullable String key, @Nullable ZipkinTrace value, @Nonnull RemovalCause cause) {
+
+    }
+
+    @Override public void addSpan(ZipkinSpan span) {
+        ZipkinTrace trace = inProcessSpanCache.getIfPresent(span.getTraceId());
+        if (trace == null) {
+            newTraceLock.lock();
+            try {
+                trace = new ZipkinTrace();
+                inProcessSpanCache.put(span.getTraceId(), 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/ZipkinReceiverConfig.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/Annotation.java
similarity index 70%
copy from apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverConfig.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/data/Annotation.java
index 9afe409..41a7cca 100644
--- a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverConfig.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/Annotation.java
@@ -16,12 +16,29 @@
  *
  */
 
-package org.apache.skywalking.apm.collector.receiver.zipkin.provider;
-
-import org.apache.skywalking.apm.collector.server.jetty.JettyServerConfig;
+package org.apache.skywalking.apm.collector.receiver.zipkin.provider.data;
 
 /**
  * @author wusheng
  */
-public class ZipkinReceiverConfig extends JettyServerConfig {
+public class Annotation {
+    private long timestamp;
+
+    private String value;
+
+    public long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
 }
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/SpanJettyHandler.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/Endpoint.java
similarity index 57%
copy from apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/handler/SpanJettyHandler.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/data/Endpoint.java
index 607a26d..f20fae3 100644
--- a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/handler/SpanJettyHandler.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/Endpoint.java
@@ -16,27 +16,49 @@
  *
  */
 
-package org.apache.skywalking.apm.collector.receiver.zipkin.provider.handler;
-
-import com.google.gson.JsonElement;
-import java.io.IOException;
-import javax.servlet.http.HttpServletRequest;
-import org.apache.skywalking.apm.collector.server.jetty.ArgumentsParseException;
-import org.apache.skywalking.apm.collector.server.jetty.JettyHandler;
+package org.apache.skywalking.apm.collector.receiver.zipkin.provider.data;
 
 /**
  * @author wusheng
  */
-public class SpanJettyHandler extends JettyHandler {
-    @Override public String pathSpec() {
-        return "/api/v2/spans";
+public class Endpoint {
+    private String serviceName;
+
+    private String ipv4;
+
+    private String ipv6;
+
+    private int port;
+
+    public String getServiceName() {
+        return serviceName;
+    }
+
+    public void setServiceName(String serviceName) {
+        this.serviceName = serviceName;
+    }
+
+    public String getIpv4() {
+        return ipv4;
+    }
+
+    public void setIpv4(String ipv4) {
+        this.ipv4 = ipv4;
+    }
+
+    public String getIpv6() {
+        return ipv6;
+    }
+
+    public void setIpv6(String ipv6) {
+        this.ipv6 = ipv6;
     }
 
-    @Override protected JsonElement doGet(HttpServletRequest req) throws ArgumentsParseException {
-        return null;
+    public int getPort() {
+        return port;
     }
 
-    @Override protected JsonElement doPost(HttpServletRequest req) throws ArgumentsParseException, IOException {
-        return null;
+    public void setPort(int port) {
+        this.port = port;
     }
 }
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/ZipkinReceiverConfig.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/Kind.java
similarity index 86%
copy from apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverConfig.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/data/Kind.java
index 9afe409..f620fb7 100644
--- a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverConfig.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/Kind.java
@@ -16,12 +16,11 @@
  *
  */
 
-package org.apache.skywalking.apm.collector.receiver.zipkin.provider;
-
-import org.apache.skywalking.apm.collector.server.jetty.JettyServerConfig;
+package org.apache.skywalking.apm.collector.receiver.zipkin.provider.data;
 
 /**
  * @author wusheng
  */
-public class ZipkinReceiverConfig extends JettyServerConfig {
+public enum Kind {
+    UNKNOWN, SERVER, CLIENT, PRODUCER, CONSUMER
 }
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/ZipkinSpan.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/ZipkinSpan.java
new file mode 100644
index 0000000..05dac0d
--- /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/ZipkinSpan.java
@@ -0,0 +1,149 @@
+/*
+ * 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 java.util.HashMap;
+import java.util.List;
+
+/**
+ * @author wusheng
+ */
+public class ZipkinSpan {
+    private String traceId;
+
+    private String id;
+
+    private String parentId;
+
+    private Long timestamp;
+
+    private Long duration;
+
+    private Kind kind;
+
+    private String name;
+
+    private Endpoint localEndpoint;
+
+    private Endpoint remoteEndpoint;
+
+    private HashMap<String, String> tags;
+
+    private boolean shared;
+
+    private List<Annotation> annotations;
+
+    public String getTraceId() {
+        return traceId;
+    }
+
+    public void setTraceId(String traceId) {
+        this.traceId = traceId;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(String parentId) {
+        this.parentId = parentId;
+    }
+
+    public Long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public Long getDuration() {
+        return duration;
+    }
+
+    public void setDuration(Long duration) {
+        this.duration = duration;
+    }
+
+    public Kind getKind() {
+        return kind;
+    }
+
+    public void setKind(Kind kind) {
+        this.kind = kind;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Endpoint getLocalEndpoint() {
+        return localEndpoint;
+    }
+
+    public void setLocalEndpoint(Endpoint localEndpoint) {
+        this.localEndpoint = localEndpoint;
+    }
+
+    public Endpoint getRemoteEndpoint() {
+        return remoteEndpoint;
+    }
+
+    public void setRemoteEndpoint(Endpoint remoteEndpoint) {
+        this.remoteEndpoint = remoteEndpoint;
+    }
+
+    public HashMap<String, String> getTags() {
+        return tags;
+    }
+
+    public void setTags(HashMap<String, String> tags) {
+        this.tags = tags;
+    }
+
+    public boolean isShared() {
+        return shared;
+    }
+
+    public void setShared(boolean shared) {
+        this.shared = shared;
+    }
+
+    public List<Annotation> getAnnotations() {
+        return annotations;
+    }
+
+    public void setAnnotations(
+        List<Annotation> annotations) {
+        this.annotations = annotations;
+    }
+}
+
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/ZipkinReceiverConfig.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
similarity index 63%
copy from apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverConfig.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/data/ZipkinTrace.java
index 9afe409..0b7b455 100644
--- a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/ZipkinReceiverConfig.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
@@ -16,12 +16,30 @@
  *
  */
 
-package org.apache.skywalking.apm.collector.receiver.zipkin.provider;
+package org.apache.skywalking.apm.collector.receiver.zipkin.provider.data;
 
-import org.apache.skywalking.apm.collector.server.jetty.JettyServerConfig;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
 
 /**
  * @author wusheng
  */
-public class ZipkinReceiverConfig extends JettyServerConfig {
+public class ZipkinTrace {
+    private List<ZipkinSpan> spans;
+    private ReentrantLock spanWriteLock;
+
+    public ZipkinTrace() {
+        spans = new LinkedList<>();
+        spanWriteLock = new ReentrantLock();
+    }
+
+    public void addSpan(ZipkinSpan span) {
+        spanWriteLock.lock();
+        try {
+            spans.add(span);
+        } finally {
+            spanWriteLock.unlock();
+        }
+    }
 }
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/SpanJettyHandler.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/SpanJettyHandler.java
index 607a26d..c295b02 100644
--- a/apm-collector/apm-collector-thirdparty-receiver/receiver-zipkin/receiver-zipkin-provider/src/main/java/org/apache/skywalking/apm/collector/receiver/zipkin/provider/handler/SpanJettyHandler.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/SpanJettyHandler.java
@@ -18,16 +18,40 @@
 
 package org.apache.skywalking.apm.collector.receiver.zipkin.provider.handler;
 
+import com.google.gson.Gson;
 import com.google.gson.JsonElement;
+import com.google.gson.reflect.TypeToken;
+import java.io.BufferedReader;
 import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.List;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.ZipkinReceiverConfig;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.cache.CacheFactory;
+import org.apache.skywalking.apm.collector.receiver.zipkin.provider.data.ZipkinSpan;
 import org.apache.skywalking.apm.collector.server.jetty.ArgumentsParseException;
 import org.apache.skywalking.apm.collector.server.jetty.JettyHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * @author wusheng
  */
 public class SpanJettyHandler extends JettyHandler {
+    private static final Logger logger = LoggerFactory.getLogger(SpanJettyHandler.class);
+
+    private Gson gson;
+    private Type spanListType;
+    private ZipkinReceiverConfig config;
+
+    public SpanJettyHandler(ZipkinReceiverConfig config) {
+        this.config = config;
+        gson = new Gson();
+        spanListType = new TypeToken<List<ZipkinSpan>>() {
+        }.getType();
+    }
+
     @Override public String pathSpec() {
         return "/api/v2/spans";
     }
@@ -36,7 +60,38 @@ public class SpanJettyHandler extends JettyHandler {
         return null;
     }
 
-    @Override protected JsonElement doPost(HttpServletRequest req) throws ArgumentsParseException, IOException {
-        return null;
+    protected void doPost(HttpServletRequest req, HttpServletResponse response) {
+        response.setContentType("application/json");
+        response.setCharacterEncoding("utf-8");
+
+        try {
+            BufferedReader br = req.getReader();
+
+            List<ZipkinSpan> spans = gson.fromJson(br, spanListType);
+            spans.forEach(span ->
+                CacheFactory.INSTANCE.get(config).addSpan(span)
+            );
+
+            response.setStatus(202);
+        } catch (Exception e) {
+            response.setStatus(500);
+
+            logger.error(e.getMessage(), e);
+        }
+    }
+
+    /**
+     * Zipkin doesn't request a Json format response.
+     * Implement {@link #doPost(HttpServletRequest, HttpServletResponse)} by following zipkin protocol.
+     * Leave this method no implementation.
+     *
+     * @param req
+     * @return
+     * @throws ArgumentsParseException
+     * @throws IOException
+     */
+    @Override
+    protected JsonElement doPost(HttpServletRequest req) throws ArgumentsParseException, IOException {
+        throw new UnsupportedOperationException();
     }
 }

-- 
To stop receiving notification emails like this one, please contact
wusheng@apache.org.