You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2018/11/12 09:42:25 UTC

[incubator-skywalking] branch master updated: New v2 header with header key `sw6` (#1894)

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 645a9a5  New v2 header with header key `sw6` (#1894)
645a9a5 is described below

commit 645a9a579d2f5f57714eafd808228591bd9d9d66
Author: 吴晟 Wu Sheng <wu...@foxmail.com>
AuthorDate: Mon Nov 12 17:42:17 2018 +0800

    New v2 header with header key `sw6` (#1894)
    
    * Add some supports to sw6 header. Break many test cases because I turn sw3 default off. For sure, you could open in agent.conf.  FYI @peng-yongsheng @ascrutae
    
    * Fix CI and make user cases still work under v1 header.
    
    * Support BASE64 in v2 header and make entryOperationName and parentOperationName optional in ContextCarrier or ContextSnapshot
    
    * Fix CI.
    
    * @peng-yongsheng This is backend related, please pay attention.
    
    * Fix the carrier item order is incorrect (#1903)
---
 .../skywalking/apm/agent/core/base64/Base64.java   |  45 +++--
 .../skywalking/apm/agent/core/conf/Config.java     |  10 ++
 .../apm/agent/core/context/ContextCarrier.java     | 170 +++++++++++++-----
 .../apm/agent/core/context/ContextSnapshot.java    |  10 +-
 .../apm/agent/core/context/SW3CarrierItem.java     |   4 +-
 .../{SW3CarrierItem.java => SW6CarrierItem.java}   |  13 +-
 .../apm/agent/core/context/TracingContext.java     |  29 +--
 .../agent/core/context/trace/TraceSegmentRef.java  |  62 ++++---
 .../core/context/ContextCarrierV2HeaderTest.java   | 195 +++++++++++++++++++++
 .../apm/agent/core/context/ContextManagerTest.java |   6 +-
 .../activemq/ActiveMQConsumerInterceptor.java      |  28 +--
 .../activemq/ActiveMQConsumerInterceptorTest.java  |  18 +-
 .../apm/plugin/dubbo/DubboInterceptorTest.java     |   7 +
 .../jetty/v9/server/HandleInterceptorTest.java     |   8 +
 .../kafka/v11/KafkaConsumerInterceptorTest.java    |   8 +
 .../plugin/motan/MotanProviderInterceptorTest.java |   9 +
 .../sofarpc/SofaRpcProviderInterceptorTest.java    |  13 +-
 .../apm/plugin/struts2/Struts2InterceptorTest.java |   8 +
 .../tomcat78x/TomcatInvokeInterceptorTest.java     |  10 +-
 .../v2x/ExecuteRootHandlerInterceptorTest.java     |  12 +-
 .../opentracing/SkywalkingSpanActivationTest.java  |  63 ++++---
 .../listener/endpoint/MultiScopesSpanListener.java |  10 +-
 .../parser/listener/endpoint/SourceBuilder.java    |   4 +
 23 files changed, 574 insertions(+), 168 deletions(-)

diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/base64/Base64.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/base64/Base64.java
index 6467862..2a526da 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/base64/Base64.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/base64/Base64.java
@@ -18,17 +18,30 @@
 package org.apache.skywalking.apm.agent.core.base64;
 
 import java.io.UnsupportedEncodingException;
+import org.apache.skywalking.apm.agent.core.logging.api.ILog;
+import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
 
 /**
- * Copied from {@code zipkin.internal.Base64}, adapted from {@code okio.Base64}
- * as JRE 6 doesn't have a base64Url encoder.
+ * Copied from {@code zipkin.internal.Base64}, adapted from {@code okio.Base64} as JRE 6 doesn't have a base64Url
+ * encoder.
  *
  * @author okio cited the original author as Alexander Y. Kleymenov
  */
 public final class Base64 {
+    private static final ILog logger = LogManager.getLogger(Base64.class);
+
     private Base64() {
     }
 
+    public static String decode2UTFString(String in) {
+        try {
+            return new String(decode(in), "utf-8");
+        } catch (UnsupportedEncodingException e) {
+            logger.error(e, "Can't decode BASE64 text {}", in);
+            return "";
+        }
+    }
+
     public static byte[] decode(String in) {
         // Ignore trailing '=' padding and whitespace from the input.
         int limit = in.length();
@@ -40,7 +53,7 @@ public final class Base64 {
         }
 
         // If the input includes whitespace, this output array will be longer than necessary.
-        byte[] out = new byte[(int) (limit * 6L / 8L)];
+        byte[] out = new byte[(int)(limit * 6L / 8L)];
         int outCount = 0;
         int inCount = 0;
 
@@ -75,14 +88,14 @@ public final class Base64 {
             }
 
             // Append this char's 6 bits to the word.
-            word = (word << 6) | (byte) bits;
+            word = (word << 6) | (byte)bits;
 
             // For every 4 chars of input, we accumulate 24 bits of output. Emit 3 bytes.
             inCount++;
             if (inCount % 4 == 0) {
-                out[outCount++] = (byte) (word >> 16);
-                out[outCount++] = (byte) (word >> 8);
-                out[outCount++] = (byte) word;
+                out[outCount++] = (byte)(word >> 16);
+                out[outCount++] = (byte)(word >> 8);
+                out[outCount++] = (byte)word;
             }
         }
 
@@ -93,16 +106,17 @@ public final class Base64 {
         } else if (lastWordChars == 2) {
             // We read 2 chars followed by "==". Emit 1 byte with 8 of those 12 bits.
             word = word << 12;
-            out[outCount++] = (byte) (word >> 16);
+            out[outCount++] = (byte)(word >> 16);
         } else if (lastWordChars == 3) {
             // We read 3 chars, followed by "=". Emit 2 bytes for 16 of those 18 bits.
             word = word << 6;
-            out[outCount++] = (byte) (word >> 16);
-            out[outCount++] = (byte) (word >> 8);
+            out[outCount++] = (byte)(word >> 16);
+            out[outCount++] = (byte)(word >> 8);
         }
 
         // If we sized our out array perfectly, we're done.
-        if (outCount == out.length) return out;
+        if (outCount == out.length)
+            return out;
 
         // Copy the decoded bytes to a new, right-sized array.
         byte[] prefix = new byte[outCount];
@@ -124,6 +138,15 @@ public final class Base64 {
         '5', '6', '7', '8', '9', '-', '_'
     };
 
+    public static String encode(String text) {
+        try {
+            return encode(text.getBytes("utf-8"));
+        } catch (UnsupportedEncodingException e) {
+            logger.error(e, "Can't encode {} in BASE64", text);
+            return "";
+        }
+    }
+
     public static String encode(byte[] in) {
         return encode(in, MAP);
     }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
index dfdea53..b44f40f 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
@@ -70,6 +70,16 @@ public class Config {
          * Skywalking team may ask for these files in order to resolve compatible problem.
          */
         public static boolean IS_OPEN_DEBUGGING_CLASS = false;
+
+        /**
+         * Active V2 header in default
+         */
+        public static boolean ACTIVE_V2_HEADER = true;
+
+        /**
+         * Deactive V1 header in default
+         */
+        public static boolean ACTIVE_V1_HEADER = false;
     }
 
     public static class Collector {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextCarrier.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextCarrier.java
index 52c5ae8..8ff218d 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextCarrier.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextCarrier.java
@@ -16,11 +16,12 @@
  *
  */
 
-
 package org.apache.skywalking.apm.agent.core.context;
 
 import java.io.Serializable;
 import java.util.List;
+import org.apache.skywalking.apm.agent.core.base64.Base64;
+import org.apache.skywalking.apm.agent.core.conf.Config;
 import org.apache.skywalking.apm.agent.core.context.ids.DistributedTraceId;
 import org.apache.skywalking.apm.agent.core.context.ids.ID;
 import org.apache.skywalking.apm.agent.core.context.ids.PropagatedTraceId;
@@ -29,8 +30,8 @@ import org.apache.skywalking.apm.agent.core.dictionary.DictionaryUtil;
 import org.apache.skywalking.apm.util.StringUtil;
 
 /**
- * {@link ContextCarrier} is a data carrier of {@link TracingContext}.
- * It holds the snapshot (current state) of {@link TracingContext}.
+ * {@link ContextCarrier} is a data carrier of {@link TracingContext}. It holds the snapshot (current state) of {@link
+ * TracingContext}.
  * <p>
  * Created by wusheng on 2017/2/17.
  */
@@ -41,8 +42,7 @@ public class ContextCarrier implements Serializable {
     private ID traceSegmentId;
 
     /**
-     * id of parent span.
-     * It is unique in parent trace segment.
+     * id of parent span. It is unique in parent trace segment.
      */
     private int spanId = -1;
 
@@ -62,14 +62,12 @@ public class ContextCarrier implements Serializable {
     private String peerHost;
 
     /**
-     * Operation/Service name of the first one in this distributed trace.
-     * This name may be compressed to an integer.
+     * Operation/Service name of the first one in this distributed trace. This name may be compressed to an integer.
      */
     private String entryOperationName;
 
     /**
-     * Operation/Service name of the parent one in this distributed trace.
-     * This name may be compressed to an integer.
+     * Operation/Service name of the parent one in this distributed trace. This name may be compressed to an integer.
      */
     private String parentOperationName;
 
@@ -79,28 +77,60 @@ public class ContextCarrier implements Serializable {
     private DistributedTraceId primaryDistributedTraceId;
 
     public CarrierItem items() {
-        SW3CarrierItem carrierItem = new SW3CarrierItem(this, null);
-        CarrierItemHead head = new CarrierItemHead(carrierItem);
+        CarrierItemHead head;
+        if (Config.Agent.ACTIVE_V2_HEADER && Config.Agent.ACTIVE_V1_HEADER) {
+            SW3CarrierItem  carrierItem = new SW3CarrierItem(this, null);
+            SW6CarrierItem sw6CarrierItem = new SW6CarrierItem(this, carrierItem);
+            head = new CarrierItemHead(sw6CarrierItem);
+        } else if (Config.Agent.ACTIVE_V2_HEADER) {
+            SW6CarrierItem sw6CarrierItem = new SW6CarrierItem(this, null);
+            head = new CarrierItemHead(sw6CarrierItem);
+        } else if (Config.Agent.ACTIVE_V1_HEADER) {
+            SW3CarrierItem carrierItem = new SW3CarrierItem(this, null);
+            head = new CarrierItemHead(carrierItem);
+        } else {
+            throw new IllegalArgumentException("At least active v1 or v2 header.");
+        }
         return head;
     }
 
     /**
-     * Serialize this {@link ContextCarrier} to a {@link String},
-     * with '|' split.
+     * Serialize this {@link ContextCarrier} to a {@link String}, with '|' split.
      *
      * @return the serialization string.
      */
-    String serialize() {
-        if (this.isValid()) {
-            return StringUtil.join('|',
-                this.getTraceSegmentId().encode(),
-                this.getSpanId() + "",
-                this.getParentApplicationInstanceId() + "",
-                this.getEntryApplicationInstanceId() + "",
-                this.getPeerHost(),
-                this.getEntryOperationName(),
-                this.getParentOperationName(),
-                this.getPrimaryDistributedTraceId().encode());
+    String serialize(HeaderVersion version) {
+        if (this.isValid(version)) {
+            if (HeaderVersion.v1.equals(version)) {
+                if (Config.Agent.ACTIVE_V1_HEADER) {
+                    return StringUtil.join('|',
+                        this.getTraceSegmentId().encode(),
+                        this.getSpanId() + "",
+                        this.getParentApplicationInstanceId() + "",
+                        this.getEntryApplicationInstanceId() + "",
+                        this.getPeerHost(),
+                        this.getEntryOperationName(),
+                        this.getParentOperationName(),
+                        this.getPrimaryDistributedTraceId().encode());
+                } else {
+                    return "";
+                }
+            } else {
+                if (Config.Agent.ACTIVE_V2_HEADER) {
+                    return StringUtil.join('-',
+                        "1",
+                        Base64.encode(this.getPrimaryDistributedTraceId().encode()),
+                        Base64.encode(this.getTraceSegmentId().encode()),
+                        this.getSpanId() + "",
+                        this.getParentApplicationInstanceId() + "",
+                        this.getEntryApplicationInstanceId() + "",
+                        Base64.encode(this.getPeerHost()),
+                        Base64.encode(this.getEntryOperationName()),
+                        Base64.encode(this.getParentOperationName()));
+                } else {
+                    return "";
+                }
+            }
         } else {
             return "";
         }
@@ -111,42 +141,83 @@ public class ContextCarrier implements Serializable {
      *
      * @param text carries {@link #traceSegmentId} and {@link #spanId}, with '|' split.
      */
-    ContextCarrier deserialize(String text) {
+    ContextCarrier deserialize(String text, HeaderVersion version) {
         if (text != null) {
-            String[] parts = text.split("\\|", 8);
-            if (parts.length == 8) {
-                try {
-                    this.traceSegmentId = new ID(parts[0]);
-                    this.spanId = Integer.parseInt(parts[1]);
-                    this.parentApplicationInstanceId = Integer.parseInt(parts[2]);
-                    this.entryApplicationInstanceId = Integer.parseInt(parts[3]);
-                    this.peerHost = parts[4];
-                    this.entryOperationName = parts[5];
-                    this.parentOperationName = parts[6];
-                    this.primaryDistributedTraceId = new PropagatedTraceId(parts[7]);
-                } catch (NumberFormatException e) {
-
+            // if this carrier is initialized by v1 or v2, don't do deserialize again for performance.
+            if (this.isValid(HeaderVersion.v1) || this.isValid(HeaderVersion.v2)) {
+                return this;
+            }
+            if (HeaderVersion.v1.equals(version)) {
+                String[] parts = text.split("\\|", 8);
+                if (parts.length == 8) {
+                    try {
+                        this.traceSegmentId = new ID(parts[0]);
+                        this.spanId = Integer.parseInt(parts[1]);
+                        this.parentApplicationInstanceId = Integer.parseInt(parts[2]);
+                        this.entryApplicationInstanceId = Integer.parseInt(parts[3]);
+                        this.peerHost = parts[4];
+                        this.entryOperationName = parts[5];
+                        this.parentOperationName = parts[6];
+                        this.primaryDistributedTraceId = new PropagatedTraceId(parts[7]);
+                    } catch (NumberFormatException e) {
+
+                    }
                 }
+            } else if (HeaderVersion.v2.equals(version)) {
+                String[] parts = text.split("\\-", 9);
+                if (parts.length == 9) {
+                    try {
+                        // parts[0] is sample flag, always trace if header exists.
+                        this.primaryDistributedTraceId = new PropagatedTraceId(Base64.decode2UTFString(parts[1]));
+                        this.traceSegmentId = new ID(Base64.decode2UTFString(parts[2]));
+                        this.spanId = Integer.parseInt(parts[3]);
+                        this.parentApplicationInstanceId = Integer.parseInt(parts[4]);
+                        this.entryApplicationInstanceId = Integer.parseInt(parts[5]);
+                        this.peerHost = Base64.decode2UTFString(parts[6]);
+                        this.entryOperationName = Base64.decode2UTFString(parts[7]);
+                        this.parentOperationName = Base64.decode2UTFString(parts[8]);
+                    } catch (NumberFormatException e) {
+
+                    }
+                }
+            } else {
+                throw new IllegalArgumentException("Unimplemented header version." + version);
             }
         }
         return this;
     }
 
+    public boolean isValid() {
+        return isValid(HeaderVersion.v2) || isValid(HeaderVersion.v1);
+    }
+
     /**
      * Make sure this {@link ContextCarrier} has been initialized.
      *
      * @return true for unbroken {@link ContextCarrier} or no-initialized. Otherwise, false;
      */
-    public boolean isValid() {
-        return traceSegmentId != null
-            && traceSegmentId.isValid()
-            && getSpanId() > -1
-            && parentApplicationInstanceId != DictionaryUtil.nullValue()
-            && entryApplicationInstanceId != DictionaryUtil.nullValue()
-            && !StringUtil.isEmpty(peerHost)
-            && !StringUtil.isEmpty(entryOperationName)
-            && !StringUtil.isEmpty(parentOperationName)
-            && primaryDistributedTraceId != null;
+    boolean isValid(HeaderVersion version) {
+        if (HeaderVersion.v1.equals(version)) {
+            return traceSegmentId != null
+                && traceSegmentId.isValid()
+                && getSpanId() > -1
+                && parentApplicationInstanceId != DictionaryUtil.nullValue()
+                && entryApplicationInstanceId != DictionaryUtil.nullValue()
+                && !StringUtil.isEmpty(peerHost)
+                && !StringUtil.isEmpty(entryOperationName)
+                && !StringUtil.isEmpty(parentOperationName)
+                && primaryDistributedTraceId != null;
+        } else if (HeaderVersion.v2.equals(version)) {
+            return traceSegmentId != null
+                && traceSegmentId.isValid()
+                && getSpanId() > -1
+                && parentApplicationInstanceId != DictionaryUtil.nullValue()
+                && entryApplicationInstanceId != DictionaryUtil.nullValue()
+                && !StringUtil.isEmpty(peerHost)
+                && primaryDistributedTraceId != null;
+        } else {
+            throw new IllegalArgumentException("Unimplemented header version." + version);
+        }
     }
 
     public String getEntryOperationName() {
@@ -229,4 +300,7 @@ public class ContextCarrier implements Serializable {
         this.entryApplicationInstanceId = entryApplicationInstanceId;
     }
 
+    public enum HeaderVersion {
+        v1, v2
+    }
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextSnapshot.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextSnapshot.java
index a235dfe..0898d0a 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextSnapshot.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextSnapshot.java
@@ -16,14 +16,12 @@
  *
  */
 
-
 package org.apache.skywalking.apm.agent.core.context;
 
 import java.util.List;
-import org.apache.skywalking.apm.agent.core.context.ids.ID;
 import org.apache.skywalking.apm.agent.core.context.ids.DistributedTraceId;
+import org.apache.skywalking.apm.agent.core.context.ids.ID;
 import org.apache.skywalking.apm.agent.core.dictionary.DictionaryUtil;
-import org.apache.skywalking.apm.util.StringUtil;
 
 /**
  * The <code>ContextSnapshot</code> is a snapshot for current context. The snapshot carries the info for building
@@ -98,9 +96,7 @@ public class ContextSnapshot {
         return traceSegmentId != null
             && spanId > -1
             && entryApplicationInstanceId != DictionaryUtil.nullValue()
-            && primaryDistributedTraceId != null
-            && !StringUtil.isEmpty(entryOperationName)
-            && !StringUtil.isEmpty(parentOperationName);
+            && primaryDistributedTraceId != null;
     }
 
     public String getEntryOperationName() {
@@ -114,7 +110,7 @@ public class ContextSnapshot {
     public int getEntryApplicationInstanceId() {
         return entryApplicationInstanceId;
     }
-    
+
     public boolean isFromCurrent() {
         return traceSegmentId.equals(ContextManager.capture().getTraceSegmentId());
     }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW3CarrierItem.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW3CarrierItem.java
index f455ebd..5d05778 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW3CarrierItem.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW3CarrierItem.java
@@ -27,12 +27,12 @@ public class SW3CarrierItem extends CarrierItem {
     private ContextCarrier carrier;
 
     public SW3CarrierItem(ContextCarrier carrier, CarrierItem next) {
-        super(HEADER_NAME, carrier.serialize(), next);
+        super(HEADER_NAME, carrier.serialize(ContextCarrier.HeaderVersion.v1), next);
         this.carrier = carrier;
     }
 
     @Override
     public void setHeadValue(String headValue) {
-        carrier.deserialize(headValue);
+        carrier.deserialize(headValue, ContextCarrier.HeaderVersion.v1);
     }
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW3CarrierItem.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW6CarrierItem.java
similarity index 76%
copy from apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW3CarrierItem.java
copy to apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW6CarrierItem.java
index f455ebd..8068fdf 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW3CarrierItem.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/SW6CarrierItem.java
@@ -16,23 +16,22 @@
  *
  */
 
-
 package org.apache.skywalking.apm.agent.core.context;
 
 /**
  * @author wusheng
  */
-public class SW3CarrierItem extends CarrierItem {
-    public static final String HEADER_NAME = "sw3";
+public class SW6CarrierItem extends CarrierItem {
+    public static final String HEADER_NAME = "sw6";
     private ContextCarrier carrier;
 
-    public SW3CarrierItem(ContextCarrier carrier, CarrierItem next) {
-        super(HEADER_NAME, carrier.serialize(), next);
+    public SW6CarrierItem(ContextCarrier carrier, CarrierItem next) {
+        super(HEADER_NAME, carrier.serialize(ContextCarrier.HeaderVersion.v2), next);
         this.carrier = carrier;
     }
 
     @Override
     public void setHeadValue(String headValue) {
-        carrier.deserialize(headValue);
+        carrier.deserialize(headValue, ContextCarrier.HeaderVersion.v2);
     }
-}
+}
\ No newline at end of file
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
index 84552bd..c4a3bf1 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
@@ -38,6 +38,7 @@ import org.apache.skywalking.apm.agent.core.dictionary.PossibleFound;
 import org.apache.skywalking.apm.agent.core.logging.api.ILog;
 import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
 import org.apache.skywalking.apm.agent.core.sampling.SamplingService;
+import org.apache.skywalking.apm.util.StringUtil;
 
 /**
  * The <code>TracingContext</code> represents a core tracing logic controller. It build the final {@link
@@ -94,8 +95,8 @@ public class TracingContext implements AbstractTracerContext {
      * Inject the context into the given carrier, only when the active span is an exit one.
      *
      * @param carrier to carry the context for crossing process.
-     * @throws IllegalStateException if the active span isn't an exit one.
-     * Ref to {@link AbstractTracerContext#inject(ContextCarrier)}
+     * @throws IllegalStateException if the active span isn't an exit one. Ref to {@link
+     * AbstractTracerContext#inject(ContextCarrier)}
      */
     @Override
     public void inject(ContextCarrier carrier) {
@@ -136,7 +137,9 @@ public class TracingContext implements AbstractTracerContext {
         carrier.setEntryApplicationInstanceId(entryApplicationInstanceId);
 
         if (operationId == DictionaryUtil.nullValue()) {
-            carrier.setEntryOperationName(operationName);
+            if (!StringUtil.isEmpty(operationName)) {
+                carrier.setEntryOperationName(operationName);
+            }
         } else {
             carrier.setEntryOperationId(operationId);
         }
@@ -154,8 +157,8 @@ public class TracingContext implements AbstractTracerContext {
     /**
      * Extract the carrier to build the reference for the pre segment.
      *
-     * @param carrier carried the context from a cross-process segment.
-     * Ref to {@link AbstractTracerContext#extract(ContextCarrier)}
+     * @param carrier carried the context from a cross-process segment. Ref to {@link
+     * AbstractTracerContext#extract(ContextCarrier)}
      */
     @Override
     public void extract(ContextCarrier carrier) {
@@ -171,8 +174,7 @@ public class TracingContext implements AbstractTracerContext {
     /**
      * Capture the snapshot of current context.
      *
-     * @return the snapshot of context for cross-thread propagation
-     * Ref to {@link AbstractTracerContext#capture()}
+     * @return the snapshot of context for cross-thread propagation Ref to {@link AbstractTracerContext#capture()}
      */
     @Override
     public ContextSnapshot capture() {
@@ -197,7 +199,9 @@ public class TracingContext implements AbstractTracerContext {
         snapshot.setEntryApplicationInstanceId(entryApplicationInstanceId);
 
         if (entryOperationId == DictionaryUtil.nullValue()) {
-            snapshot.setEntryOperationName(entryOperationName);
+            if (!StringUtil.isEmpty(entryOperationName)) {
+                snapshot.setEntryOperationName(entryOperationName);
+            }
         } else {
             snapshot.setEntryOperationId(entryOperationId);
         }
@@ -213,8 +217,7 @@ public class TracingContext implements AbstractTracerContext {
     /**
      * Continue the context from the given snapshot of parent thread.
      *
-     * @param snapshot from {@link #capture()} in the parent thread.
-     * Ref to {@link AbstractTracerContext#continued(ContextSnapshot)}
+     * @param snapshot from {@link #capture()} in the parent thread. Ref to {@link AbstractTracerContext#continued(ContextSnapshot)}
      */
     @Override
     public void continued(ContextSnapshot snapshot) {
@@ -236,8 +239,7 @@ public class TracingContext implements AbstractTracerContext {
      * Create an entry span
      *
      * @param operationName most likely a service name
-     * @return span instance.
-     * Ref to {@link EntrySpan}
+     * @return span instance. Ref to {@link EntrySpan}
      */
     @Override
     public AbstractSpan createEntrySpan(final String operationName) {
@@ -282,8 +284,7 @@ public class TracingContext implements AbstractTracerContext {
      * Create a local span
      *
      * @param operationName most likely a local method signature, or business name.
-     * @return the span represents a local logic block.
-     * Ref to {@link LocalSpan}
+     * @return the span represents a local logic block. Ref to {@link LocalSpan}
      */
     @Override
     public AbstractSpan createLocalSpan(final String operationName) {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/TraceSegmentRef.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/TraceSegmentRef.java
index 5ea44f6..ef3f287 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/TraceSegmentRef.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/TraceSegmentRef.java
@@ -16,7 +16,6 @@
  *
  */
 
-
 package org.apache.skywalking.apm.agent.core.context.trace;
 
 import org.apache.skywalking.apm.agent.core.conf.RemoteDownstreamConfig;
@@ -24,11 +23,13 @@ import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
 import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
 import org.apache.skywalking.apm.agent.core.context.ids.ID;
 import org.apache.skywalking.apm.agent.core.dictionary.DictionaryUtil;
-import org.apache.skywalking.apm.network.language.agent.*;
+import org.apache.skywalking.apm.network.language.agent.RefType;
+import org.apache.skywalking.apm.network.language.agent.TraceSegmentReference;
+import org.apache.skywalking.apm.util.StringUtil;
 
 /**
- * {@link TraceSegmentRef} is like a pointer, which ref to another {@link TraceSegment},
- * use {@link #spanId} point to the exact span of the ref {@link TraceSegment}.
+ * {@link TraceSegmentRef} is like a pointer, which ref to another {@link TraceSegment}, use {@link #spanId} point to
+ * the exact span of the ref {@link TraceSegment}.
  * <p>
  * Created by wusheng on 2017/2/17.
  */
@@ -73,16 +74,20 @@ public class TraceSegmentRef {
             this.peerId = Integer.parseInt(host);
         }
         String entryOperationName = carrier.getEntryOperationName();
-        if (entryOperationName.charAt(0) == '#') {
-            this.entryOperationName = entryOperationName.substring(1);
-        } else {
-            this.entryOperationId = Integer.parseInt(entryOperationName);
+        if (!StringUtil.isEmpty(entryOperationName)) {
+            if (entryOperationName.charAt(0) == '#') {
+                this.entryOperationName = entryOperationName.substring(1);
+            } else {
+                this.entryOperationId = Integer.parseInt(entryOperationName);
+            }
         }
         String parentOperationName = carrier.getParentOperationName();
-        if (parentOperationName.charAt(0) == '#') {
-            this.parentOperationName = parentOperationName.substring(1);
-        } else {
-            this.parentOperationId = Integer.parseInt(parentOperationName);
+        if (!StringUtil.isEmpty(parentOperationName)) {
+            if (parentOperationName.charAt(0) == '#') {
+                this.parentOperationName = parentOperationName.substring(1);
+            } else {
+                this.parentOperationId = Integer.parseInt(parentOperationName);
+            }
         }
     }
 
@@ -93,16 +98,20 @@ public class TraceSegmentRef {
         this.parentApplicationInstanceId = RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID;
         this.entryApplicationInstanceId = snapshot.getEntryApplicationInstanceId();
         String entryOperationName = snapshot.getEntryOperationName();
-        if (entryOperationName.charAt(0) == '#') {
-            this.entryOperationName = entryOperationName.substring(1);
-        } else {
-            this.entryOperationId = Integer.parseInt(entryOperationName);
+        if (!StringUtil.isEmpty(entryOperationName)) {
+            if (entryOperationName.charAt(0) == '#') {
+                this.entryOperationName = entryOperationName.substring(1);
+            } else {
+                this.entryOperationId = Integer.parseInt(entryOperationName);
+            }
         }
         String parentOperationName = snapshot.getParentOperationName();
-        if (parentOperationName.charAt(0) == '#') {
-            this.parentOperationName = parentOperationName.substring(1);
-        } else {
-            this.parentOperationId = Integer.parseInt(parentOperationName);
+        if (!StringUtil.isEmpty(parentOperationName)) {
+            if (parentOperationName.charAt(0) == '#') {
+                this.parentOperationName = parentOperationName.substring(1);
+            } else {
+                this.parentOperationId = Integer.parseInt(parentOperationName);
+            }
         }
     }
 
@@ -135,13 +144,22 @@ public class TraceSegmentRef {
         refBuilder.setEntryApplicationInstanceId(entryApplicationInstanceId);
         refBuilder.setParentTraceSegmentId(traceSegmentId.transform());
         refBuilder.setParentSpanId(spanId);
+        /**
+         * entryOperationId/entryOperationName and parentOperationId/parentOperationName could be empty at same time.
+         * This is accepted in v2 format.
+         *
+         */
         if (entryOperationId == DictionaryUtil.nullValue()) {
-            refBuilder.setEntryServiceName(entryOperationName);
+            if (!StringUtil.isEmpty(entryOperationName)) {
+                refBuilder.setEntryServiceName(entryOperationName);
+            }
         } else {
             refBuilder.setEntryServiceId(entryOperationId);
         }
         if (parentOperationId == DictionaryUtil.nullValue()) {
-            refBuilder.setParentServiceName(parentOperationName);
+            if (!StringUtil.isEmpty(parentOperationName)) {
+                refBuilder.setParentServiceName(parentOperationName);
+            }
         } else {
             refBuilder.setParentServiceId(parentOperationId);
         }
diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/ContextCarrierV2HeaderTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/ContextCarrierV2HeaderTest.java
new file mode 100644
index 0000000..00f4d9f
--- /dev/null
+++ b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/ContextCarrierV2HeaderTest.java
@@ -0,0 +1,195 @@
+/*
+ * 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.agent.core.context;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.skywalking.apm.agent.core.conf.Config;
+import org.apache.skywalking.apm.agent.core.context.ids.DistributedTraceId;
+import org.apache.skywalking.apm.agent.core.context.ids.ID;
+import org.apache.skywalking.apm.agent.core.context.ids.PropagatedTraceId;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ContextCarrierV2HeaderTest {
+    @Test
+    public void testCompatibleHeaderKeys() {
+        Config.Agent.ACTIVE_V1_HEADER = true;
+        ContextCarrier contextCarrier = new ContextCarrier();
+        CarrierItem next = contextCarrier.items();
+        boolean hasSW3 = false;
+        boolean hasSW6 = false;
+        try {
+            while (next.hasNext()) {
+                next = next.next();
+                if (next.getHeadKey().equals("sw3")) {
+                    hasSW3 = true;
+                } else if (next.getHeadKey().equals("sw6")) {
+                    hasSW6 = true;
+                } else {
+                    Assert.fail("unexpected key");
+                }
+            }
+        } finally {
+            Config.Agent.ACTIVE_V1_HEADER = false;
+        }
+        Assert.assertTrue(hasSW3);
+        Assert.assertTrue(hasSW6);
+    }
+
+    @Test
+    public void testDeserializeV2Header() {
+        ContextCarrier contextCarrier = new ContextCarrier();
+        CarrierItem next = contextCarrier.items();
+        while (next.hasNext()) {
+            next = next.next();
+            if (next.getHeadKey().equals("sw3")) {
+            } else if (next.getHeadKey().equals("sw6")) {
+                next.setHeadValue("1-My40LjU=-MS4yLjM=-4-1-1-IzEyNy4wLjAuMTo4MDgw--");
+            } else {
+                Assert.fail("unexpected key");
+            }
+        }
+
+        Assert.assertTrue(contextCarrier.isValid());
+
+        Config.Agent.ACTIVE_V1_HEADER = true;
+        try {
+            contextCarrier = new ContextCarrier();
+            next = contextCarrier.items();
+            while (next.hasNext()) {
+                next = next.next();
+                if (next.getHeadKey().equals("sw3")) {
+                    next.setHeadValue("1.2343.234234234|1|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|1.2343.234234234");
+                } else if (next.getHeadKey().equals("sw6")) {
+                } else {
+                    Assert.fail("unexpected key");
+                }
+            }
+        } finally {
+            Config.Agent.ACTIVE_V1_HEADER = false;
+        }
+
+        Assert.assertTrue(contextCarrier.isValid());
+    }
+
+    @Test
+    public void testSerializeV2Header() {
+        List<DistributedTraceId> distributedTraceIds = new ArrayList<DistributedTraceId>();
+        distributedTraceIds.add(new PropagatedTraceId("3.4.5"));
+
+        ContextCarrier contextCarrier = new ContextCarrier();
+        contextCarrier.setTraceSegmentId(new ID(1, 2, 3));
+        contextCarrier.setDistributedTraceIds(distributedTraceIds);
+        contextCarrier.setSpanId(4);
+        contextCarrier.setEntryApplicationInstanceId(1);
+        contextCarrier.setParentApplicationInstanceId(1);
+        contextCarrier.setPeerHost("127.0.0.1:8080");
+        contextCarrier.setEntryOperationName("/portal");
+        contextCarrier.setParentOperationId(123);
+
+        CarrierItem next = contextCarrier.items();
+        while (next.hasNext()) {
+            next = next.next();
+            if (next.getHeadKey().equals("sw3")) {
+                Assert.assertEquals("", next.getHeadValue());
+            } else if (next.getHeadKey().equals("sw6")) {
+                /**
+                 * sampleFlag-traceId-segmentId-spanId-parentAppInstId-entryAppInstId-peerHost-entryEndpoint-parentEndpoint
+                 *
+                 * "1-3.4.5-1.2.3-4-1-1-#127.0.0.1:8080-#/portal-123"
+                 */
+                Assert.assertEquals("1-My40LjU=-MS4yLjM=-4-1-1-IzEyNy4wLjAuMTo4MDgw-Iy9wb3J0YWw=-MTIz", next.getHeadValue());
+            } else {
+                Assert.fail("unexpected key");
+            }
+        }
+
+        Config.Agent.ACTIVE_V1_HEADER = true;
+        try {
+            next = contextCarrier.items();
+            while (next.hasNext()) {
+                next = next.next();
+                if (next.getHeadKey().equals("sw3")) {
+                    Assert.assertEquals("1.2.3|4|1|1|#127.0.0.1:8080|#/portal|123|3.4.5", next.getHeadValue());
+                } else if (next.getHeadKey().equals("sw6")) {
+                    //TODO, no BASE64
+                    Assert.assertEquals("1-My40LjU=-MS4yLjM=-4-1-1-IzEyNy4wLjAuMTo4MDgw-Iy9wb3J0YWw=-MTIz", next.getHeadValue());
+                } else {
+                    Assert.fail("unexpected key");
+                }
+            }
+
+        } finally {
+            Config.Agent.ACTIVE_V1_HEADER = false;
+        }
+
+        Assert.assertTrue(contextCarrier.isValid());
+    }
+
+    @Test
+    public void testV2HeaderAccurate() {
+        List<DistributedTraceId> distributedTraceIds = new ArrayList<DistributedTraceId>();
+        distributedTraceIds.add(new PropagatedTraceId("3.4.5"));
+
+        ContextCarrier contextCarrier = new ContextCarrier();
+        contextCarrier.setTraceSegmentId(new ID(1, 2, 3));
+        contextCarrier.setDistributedTraceIds(distributedTraceIds);
+        contextCarrier.setSpanId(4);
+        contextCarrier.setEntryApplicationInstanceId(1);
+        contextCarrier.setParentApplicationInstanceId(1);
+        contextCarrier.setPeerHost("127.0.0.1:8080");
+        contextCarrier.setEntryOperationName("/portal");
+        contextCarrier.setParentOperationId(123);
+
+        CarrierItem next = contextCarrier.items();
+        String headerValue = null;
+        while (next.hasNext()) {
+            next = next.next();
+            if (next.getHeadKey().equals("sw3")) {
+                Assert.assertEquals("", next.getHeadValue());
+            } else if (next.getHeadKey().equals("sw6")) {
+                headerValue = next.getHeadValue();
+            } else {
+                Assert.fail("unexpected key");
+            }
+        }
+
+        ContextCarrier contextCarrier2 = new ContextCarrier();
+        next = contextCarrier2.items();
+        while (next.hasNext()) {
+            next = next.next();
+            if (next.getHeadKey().equals("sw3")) {
+            } else if (next.getHeadKey().equals("sw6")) {
+                next.setHeadValue(headerValue);
+            } else {
+                Assert.fail("unexpected key");
+            }
+        }
+
+        Assert.assertTrue(contextCarrier2.isValid());
+        Assert.assertEquals(contextCarrier.getSpanId(), contextCarrier2.getSpanId());
+        Assert.assertEquals(contextCarrier.getPeerHost(), contextCarrier2.getPeerHost());
+        Assert.assertEquals(contextCarrier.getDistributedTraceId(), contextCarrier2.getDistributedTraceId());
+        Assert.assertEquals(contextCarrier.getTraceSegmentId(), contextCarrier2.getTraceSegmentId());
+        Assert.assertEquals(contextCarrier.getEntryOperationName(), contextCarrier2.getEntryOperationName());
+        Assert.assertEquals(contextCarrier.getEntryApplicationInstanceId(), contextCarrier2.getEntryApplicationInstanceId());
+        Assert.assertEquals(contextCarrier.getParentApplicationInstanceId(), contextCarrier2.getParentApplicationInstanceId());
+    }
+}
diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/ContextManagerTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/ContextManagerTest.java
index 659fe32..9da466a 100644
--- a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/ContextManagerTest.java
+++ b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/ContextManagerTest.java
@@ -80,7 +80,7 @@ public class ContextManagerTest {
 
     @Test
     public void createSpanWithInvalidateContextCarrier() {
-        ContextCarrier contextCarrier = new ContextCarrier().deserialize("#AQA=#AQA=4WcWe0tQNQA=|1|#127.0.0.1:8080|#/testEntrySpan|#/testEntrySpan|#AQA=#AQA=Et0We0tQNQA=");
+        ContextCarrier contextCarrier = new ContextCarrier().deserialize("#AQA=#AQA=4WcWe0tQNQA=|1|#127.0.0.1:8080|#/testEntrySpan|#/testEntrySpan|#AQA=#AQA=Et0We0tQNQA=", ContextCarrier.HeaderVersion.v1);
 
         AbstractSpan firstEntrySpan = ContextManager.createEntrySpan("/testEntrySpan", contextCarrier);
         firstEntrySpan.setComponent(ComponentsDefine.TOMCAT);
@@ -104,7 +104,7 @@ public class ContextManagerTest {
 
     @Test
     public void createMultipleEntrySpan() {
-        ContextCarrier contextCarrier = new ContextCarrier().deserialize("1.2343.234234234|1|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|1.2343.234234234");
+        ContextCarrier contextCarrier = new ContextCarrier().deserialize("1.2343.234234234|1|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|1.2343.234234234", ContextCarrier.HeaderVersion.v1);
         assertTrue(contextCarrier.isValid());
 
         AbstractSpan firstEntrySpan = ContextManager.createEntrySpan("/testFirstEntry", contextCarrier);
@@ -227,7 +227,7 @@ public class ContextManagerTest {
 
     @Test
     public void testTransform() throws InvalidProtocolBufferException {
-        ContextCarrier contextCarrier = new ContextCarrier().deserialize("1.234.1983829|3|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|1.2343.234234234");
+        ContextCarrier contextCarrier = new ContextCarrier().deserialize("1.234.1983829|3|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|1.2343.234234234", ContextCarrier.HeaderVersion.v1);
         assertTrue(contextCarrier.isValid());
 
         AbstractSpan firstEntrySpan = ContextManager.createEntrySpan("/testFirstEntry", contextCarrier);
diff --git a/apm-sniffer/apm-sdk-plugin/activemq-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/ActiveMQConsumerInterceptor.java b/apm-sniffer/apm-sdk-plugin/activemq-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/ActiveMQConsumerInterceptor.java
index be81bf5..f4d3706 100644
--- a/apm-sniffer/apm-sdk-plugin/activemq-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/ActiveMQConsumerInterceptor.java
+++ b/apm-sniffer/apm-sdk-plugin/activemq-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/activemq/ActiveMQConsumerInterceptor.java
@@ -18,6 +18,7 @@
 
 package org.apache.skywalking.apm.plugin.activemq;
 
+import java.lang.reflect.Method;
 import org.apache.activemq.command.MessageDispatch;
 import org.apache.skywalking.apm.agent.core.context.CarrierItem;
 import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
@@ -30,8 +31,6 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceM
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
 import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
 
-import java.lang.reflect.Method;
-
 /**
  * @author withlin
  */
@@ -43,17 +42,19 @@ public class ActiveMQConsumerInterceptor implements InstanceMethodsAroundInterce
     public static final byte TOPIC_TYPE = 2;
     public static final byte TEMP_TOPIC_TYPE = 6;
     public static final byte TEMP_QUEUE_TYPE = 5;
+
     @Override
-    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        MethodInterceptResult result) throws Throwable {
         ContextCarrier contextCarrier = new ContextCarrier();
-        String url = (String) objInst.getSkyWalkingDynamicField();
-        MessageDispatch messageDispatch = (MessageDispatch) allArguments[0];
+        String url = (String)objInst.getSkyWalkingDynamicField();
+        MessageDispatch messageDispatch = (MessageDispatch)allArguments[0];
         AbstractSpan activeSpan = null;
-        if (messageDispatch.getDestination().getDestinationType() == QUEUE_TYPE ||  messageDispatch.getDestination().getDestinationType() == TEMP_QUEUE_TYPE) {
+        if (messageDispatch.getDestination().getDestinationType() == QUEUE_TYPE || messageDispatch.getDestination().getDestinationType() == TEMP_QUEUE_TYPE) {
             activeSpan = ContextManager.createEntrySpan(OPERATE_NAME_PREFIX + "Queue/" + messageDispatch.getDestination().getPhysicalName() + CONSUMER_OPERATE_NAME_SUFFIX, null).start(System.currentTimeMillis());
             Tags.MQ_BROKER.set(activeSpan, url);
             Tags.MQ_QUEUE.set(activeSpan, messageDispatch.getDestination().getPhysicalName());
-        } else if (messageDispatch.getDestination().getDestinationType() == TOPIC_TYPE ||  messageDispatch.getDestination().getDestinationType() == TEMP_TOPIC_TYPE) {
+        } else if (messageDispatch.getDestination().getDestinationType() == TOPIC_TYPE || messageDispatch.getDestination().getDestinationType() == TEMP_TOPIC_TYPE) {
             activeSpan = ContextManager.createEntrySpan(OPERATE_NAME_PREFIX + "Topic/" + messageDispatch.getDestination().getPhysicalName() + CONSUMER_OPERATE_NAME_SUFFIX, null).start(System.currentTimeMillis());
             Tags.MQ_BROKER.set(activeSpan, url);
             Tags.MQ_TOPIC.set(activeSpan, messageDispatch.getDestination().getPhysicalName());
@@ -63,23 +64,26 @@ public class ActiveMQConsumerInterceptor implements InstanceMethodsAroundInterce
         CarrierItem next = contextCarrier.items();
         while (next.hasNext()) {
             next = next.next();
-            next.setHeadValue(messageDispatch.getMessage().getProperty(next.getHeadKey()).toString());
+            Object propertyValue = messageDispatch.getMessage().getProperty(next.getHeadKey());
+            if (propertyValue != null) {
+                next.setHeadValue(propertyValue.toString());
+            }
         }
         ContextManager.extract(contextCarrier);
 
-
     }
 
-
     @Override
-    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Object ret) throws Throwable {
+    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        Object ret) throws Throwable {
         ContextManager.stopSpan();
         return ret;
 
     }
 
     @Override
-    public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
+    public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
+        Class<?>[] argumentsTypes, Throwable t) {
         ContextManager.activeSpan().errorOccurred().log(t);
     }
 }
diff --git a/apm-sniffer/apm-sdk-plugin/activemq-5.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/activemq/ActiveMQConsumerInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/activemq-5.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/activemq/ActiveMQConsumerInterceptorTest.java
index ea77903..38e7dec 100644
--- a/apm-sniffer/apm-sdk-plugin/activemq-5.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/activemq/ActiveMQConsumerInterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/activemq-5.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/activemq/ActiveMQConsumerInterceptorTest.java
@@ -16,7 +16,6 @@
  *
  */
 
-
 package org.apache.skywalking.apm.plugin.activemq;
 
 import org.apache.activemq.command.ActiveMQDestination;
@@ -24,6 +23,7 @@ import org.apache.activemq.command.Message;
 import org.apache.activemq.command.MessageDispatch;
 import org.apache.activemq.command.Response;
 import org.apache.activemq.state.CommandVisitor;
+import org.apache.skywalking.apm.agent.core.conf.Config;
 import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
 import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
@@ -62,7 +62,7 @@ public class ActiveMQConsumerInterceptorTest {
 
     private MessageDispatch messageDispatch;
 
-    public  class  Des extends ActiveMQDestination {
+    public class Des extends ActiveMQDestination {
 
         @Override
         protected String getQualifiedPrefix() {
@@ -80,7 +80,7 @@ public class ActiveMQConsumerInterceptorTest {
         }
     }
 
-    public  class  Msg extends Message {
+    public class Msg extends Message {
 
         @Override
         public Message copy() {
@@ -126,22 +126,28 @@ public class ActiveMQConsumerInterceptorTest {
 
     @Before
     public void setUp() throws IOException {
+        Config.Agent.ACTIVE_V1_HEADER = true;
         activeMQConsumerInterceptor = new ActiveMQConsumerInterceptor();
         messageDispatch = new MessageDispatch();
 
         Des des = new Des();
         des.setPhysicalName("test");
         messageDispatch.setDestination(des);
-        Message msg =  new Msg();
-        msg.setProperty("sw3","");
+        Message msg = new Msg();
+        msg.setProperty("sw3", "");
         messageDispatch.setMessage(msg);
         arguments = new Object[] {messageDispatch};
         argumentType = null;
     }
 
+    @After
+    public void clear() {
+        Config.Agent.ACTIVE_V1_HEADER = false;
+    }
+
     @Test
     public void testConsumerWithoutMessage() throws Throwable {
-        activeMQConsumerInterceptor.beforeMethod(enhancedInstance,null,arguments,null,null);
+        activeMQConsumerInterceptor.beforeMethod(enhancedInstance, null, arguments, null, null);
         activeMQConsumerInterceptor.afterMethod(enhancedInstance, null, arguments, null, null);
 
         List<TraceSegment> traceSegments = segmentStorage.getTraceSegments();
diff --git a/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/test/java/org/apache/skywalking/apm/plugin/dubbo/DubboInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/test/java/org/apache/skywalking/apm/plugin/dubbo/DubboInterceptorTest.java
index 4011eb3..a9b0fd4 100644
--- a/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/test/java/org/apache/skywalking/apm/plugin/dubbo/DubboInterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/test/java/org/apache/skywalking/apm/plugin/dubbo/DubboInterceptorTest.java
@@ -44,6 +44,7 @@ import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
 import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
 import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
 import org.hamcrest.CoreMatchers;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -93,6 +94,7 @@ public class DubboInterceptorTest {
 
     @Before
     public void setUp() throws Exception {
+        Config.Agent.ACTIVE_V1_HEADER = true;
         dubboInterceptor = new DubboInterceptor();
 
         PowerMockito.mockStatic(RpcContext.class);
@@ -108,6 +110,11 @@ public class DubboInterceptorTest {
         Config.Agent.APPLICATION_CODE = "DubboTestCases-APP";
     }
 
+    @After
+    public void clear() {
+        Config.Agent.ACTIVE_V1_HEADER = false;
+    }
+
     @Test
     public void testServiceFromPlugin() {
         PluginBootService service = ServiceManager.INSTANCE.findService(PluginBootService.class);
diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptorTest.java
index bafc483..bf6958b 100644
--- a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptorTest.java
@@ -19,6 +19,7 @@
 package org.apache.skywalking.apm.plugin.jetty.v9.server;
 
 import java.util.List;
+import org.apache.skywalking.apm.agent.core.conf.Config;
 import org.apache.skywalking.apm.agent.core.context.SW3CarrierItem;
 import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
 import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity;
@@ -44,6 +45,7 @@ import org.eclipse.jetty.server.HttpInput;
 import org.eclipse.jetty.server.HttpTransport;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.Response;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -84,6 +86,7 @@ public class HandleInterceptorTest {
 
     @Before
     public void setUp() throws Exception {
+        Config.Agent.ACTIVE_V1_HEADER = true;
         jettyInvokeInterceptor = new HandleInterceptor();
         when(request.getRequestURI()).thenReturn("/test/testRequestURL");
         when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/test/testRequestURL"));
@@ -95,6 +98,11 @@ public class HandleInterceptorTest {
 
     }
 
+    @After
+    public void clear() {
+        Config.Agent.ACTIVE_V1_HEADER = false;
+    }
+
     @Test
     public void testWithoutSerializedContextData() throws Throwable {
         jettyInvokeInterceptor.beforeMethod(service, null, arguments, argumentType, methodInterceptResult);
diff --git a/apm-sniffer/apm-sdk-plugin/kafka-v1-plugin/src/test/java/org/apache/skywalking/apm/plugin/kafka/v11/KafkaConsumerInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/kafka-v1-plugin/src/test/java/org/apache/skywalking/apm/plugin/kafka/v11/KafkaConsumerInterceptorTest.java
index 3f876bf..4383d08 100644
--- a/apm-sniffer/apm-sdk-plugin/kafka-v1-plugin/src/test/java/org/apache/skywalking/apm/plugin/kafka/v11/KafkaConsumerInterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/kafka-v1-plugin/src/test/java/org/apache/skywalking/apm/plugin/kafka/v11/KafkaConsumerInterceptorTest.java
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Map;
 import org.apache.kafka.clients.consumer.ConsumerRecord;
 import org.apache.kafka.common.TopicPartition;
+import org.apache.skywalking.apm.agent.core.conf.Config;
 import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
 import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
 import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
@@ -39,6 +40,7 @@ import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
 import org.apache.skywalking.apm.plugin.kafka.v1.ConsumerEnhanceRequiredInfo;
 import org.apache.skywalking.apm.plugin.kafka.v1.KafkaConsumerInterceptor;
 import org.hamcrest.MatcherAssert;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -78,6 +80,7 @@ public class KafkaConsumerInterceptorTest {
 
     @Before
     public void setUp() {
+        Config.Agent.ACTIVE_V1_HEADER = true;
         consumerInterceptor = new KafkaConsumerInterceptor();
         consumerEnhanceRequiredInfo = new ConsumerEnhanceRequiredInfo();
 
@@ -99,6 +102,11 @@ public class KafkaConsumerInterceptorTest {
         messages.put(topicPartition, records);
     }
 
+    @After
+    public void clear() {
+        Config.Agent.ACTIVE_V1_HEADER = false;
+    }
+
     @Test
     public void testConsumerWithoutMessage() throws Throwable {
         consumerInterceptor.beforeMethod(consumerInstance, null, new Object[0], new Class[0], null);
diff --git a/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/apache/skywalking/apm/plugin/motan/MotanProviderInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/apache/skywalking/apm/plugin/motan/MotanProviderInterceptorTest.java
index f0dae8f..cfe42d1 100644
--- a/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/apache/skywalking/apm/plugin/motan/MotanProviderInterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/apache/skywalking/apm/plugin/motan/MotanProviderInterceptorTest.java
@@ -24,6 +24,7 @@ import com.weibo.api.motan.rpc.Response;
 import com.weibo.api.motan.rpc.URL;
 import java.util.HashMap;
 import java.util.List;
+import org.apache.skywalking.apm.agent.core.conf.Config;
 import org.apache.skywalking.apm.agent.core.context.SW3CarrierItem;
 import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
 import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
@@ -37,6 +38,7 @@ import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
 import org.apache.skywalking.apm.agent.test.tools.SpanAssert;
 import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
 import org.hamcrest.MatcherAssert;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -81,6 +83,7 @@ public class MotanProviderInterceptorTest {
 
     @Before
     public void setUp() {
+        Config.Agent.ACTIVE_V1_HEADER = true;
         invokeInterceptor = new MotanProviderInterceptor();
         url = URL.valueOf("motan://127.0.0.1:34000/org.apache.skywalking.apm.test.TestService");
 
@@ -92,6 +95,12 @@ public class MotanProviderInterceptorTest {
         when(request.getParamtersDesc()).thenReturn("java.lang.String, java.lang.Object");
     }
 
+
+    @After
+    public void clear() {
+        Config.Agent.ACTIVE_V1_HEADER = false;
+    }
+
     @Test
     public void testInvokerWithoutRefSegment() throws Throwable {
         invokeInterceptor.beforeMethod(enhancedInstance, null, arguments, argumentType, null);
diff --git a/apm-sniffer/apm-sdk-plugin/sofarpc-plugin/src/test/java/org/apache/skywalking/apm/plugin/sofarpc/SofaRpcProviderInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/sofarpc-plugin/src/test/java/org/apache/skywalking/apm/plugin/sofarpc/SofaRpcProviderInterceptorTest.java
index 4ff2370..b3cabbf 100644
--- a/apm-sniffer/apm-sdk-plugin/sofarpc-plugin/src/test/java/org/apache/skywalking/apm/plugin/sofarpc/SofaRpcProviderInterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/sofarpc-plugin/src/test/java/org/apache/skywalking/apm/plugin/sofarpc/SofaRpcProviderInterceptorTest.java
@@ -40,6 +40,7 @@ import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
 import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
 import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
 import org.hamcrest.CoreMatchers;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -81,17 +82,18 @@ public class SofaRpcProviderInterceptorTest {
     @Mock
     private ProviderInvoker invoker;
 
-    private SofaRequest           sofaRequest = PowerMockito.mock(SofaRequest.class);
+    private SofaRequest sofaRequest = PowerMockito.mock(SofaRequest.class);
     @Mock
     private MethodInterceptResult methodInterceptResult;
 
     private SofaResponse sofaResponse = PowerMockito.mock(SofaResponse.class);
 
     private Object[] allArguments;
-    private Class[]  argumentTypes;
+    private Class[] argumentTypes;
 
     @Before
     public void setUp() throws Exception {
+        Config.Agent.ACTIVE_V1_HEADER = true;
         sofaRpcProviderInterceptor = new SofaRpcProviderInterceptor();
 
         PowerMockito.mockStatic(RpcInternalContext.class);
@@ -111,11 +113,16 @@ public class SofaRpcProviderInterceptorTest {
         Config.Agent.APPLICATION_CODE = "SOFARPC-TestCases-APP";
     }
 
+    @After
+    public void clear() {
+        Config.Agent.ACTIVE_V1_HEADER = false;
+    }
+
     @Test
     public void testProviderWithAttachment() throws Throwable {
         when(rpcContext.isConsumerSide()).thenReturn(false);
         when(sofaRequest.getRequestProp(SKYWALKING_PREFIX + SW3CarrierItem.HEADER_NAME)).thenReturn(
-                "1.323.4433|3|1|1|#192.168.1.8 :18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
+            "1.323.4433|3|1|1|#192.168.1.8 :18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*");
 
         sofaRpcProviderInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentTypes, methodInterceptResult);
         sofaRpcProviderInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentTypes, sofaResponse);
diff --git a/apm-sniffer/apm-sdk-plugin/struts2-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/struts2/Struts2InterceptorTest.java b/apm-sniffer/apm-sdk-plugin/struts2-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/struts2/Struts2InterceptorTest.java
index 214183c..a5957d1 100644
--- a/apm-sniffer/apm-sdk-plugin/struts2-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/struts2/Struts2InterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/struts2-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/struts2/Struts2InterceptorTest.java
@@ -23,7 +23,9 @@ import com.opensymphony.xwork2.ActionContext;
 import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import org.apache.skywalking.apm.agent.core.conf.Config;
 import org.apache.struts2.StrutsStatics;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -92,6 +94,7 @@ public class Struts2InterceptorTest {
 
     @Before
     public void setUp() throws Exception {
+        Config.Agent.ACTIVE_V1_HEADER = true;
         struts2Interceptor = new Struts2Interceptor();
         when(request.getRequestURI()).thenReturn("/test/testRequestURL");
         when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/test/testRequestURL"));
@@ -110,6 +113,11 @@ public class Struts2InterceptorTest {
         exceptionArgumentType = new Class[] {request.getClass(), response.getClass(), new RuntimeException().getClass()};
     }
 
+    @After
+    public void clear() {
+        Config.Agent.ACTIVE_V1_HEADER = false;
+    }
+
     @Test
     public void testWithoutSerializedContextData() throws Throwable {
         struts2Interceptor.beforeMethod(enhancedInstance, null, arguments, argumentType, methodInterceptResult);
diff --git a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/tomcat78x/TomcatInvokeInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/tomcat78x/TomcatInvokeInterceptorTest.java
index b230128..7b5a8f4 100644
--- a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/tomcat78x/TomcatInvokeInterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/tomcat78x/TomcatInvokeInterceptorTest.java
@@ -16,12 +16,12 @@
  *
  */
 
-
 package org.apache.skywalking.apm.plugin.tomcat78x;
 
 import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import org.apache.skywalking.apm.agent.core.conf.Config;
 import org.apache.skywalking.apm.agent.core.context.SW3CarrierItem;
 import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
 import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
@@ -31,6 +31,7 @@ import org.apache.skywalking.apm.agent.test.helper.SpanHelper;
 import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
 import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
 import org.apache.skywalking.apm.agent.test.tools.SpanAssert;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -82,6 +83,8 @@ public class TomcatInvokeInterceptorTest {
 
     @Before
     public void setUp() throws Exception {
+        Config.Agent.ACTIVE_V1_HEADER = true;
+
         tomcatInvokeInterceptor = new TomcatInvokeInterceptor();
         tomcatExceptionInterceptor = new TomcatExceptionInterceptor();
         when(request.getRequestURI()).thenReturn("/test/testRequestURL");
@@ -94,6 +97,11 @@ public class TomcatInvokeInterceptorTest {
         exceptionArgumentType = new Class[] {request.getClass(), response.getClass(), new RuntimeException().getClass()};
     }
 
+    @After
+    public void clear() {
+        Config.Agent.ACTIVE_V1_HEADER = false;
+    }
+
     @Test
     public void testWithoutSerializedContextData() throws Throwable {
         tomcatInvokeInterceptor.beforeMethod(enhancedInstance, null, arguments, argumentType, methodInterceptResult);
diff --git a/apm-sniffer/apm-sdk-plugin/undertow-plugins/undertow-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/undertow/v2x/ExecuteRootHandlerInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/undertow-plugins/undertow-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/undertow/v2x/ExecuteRootHandlerInterceptorTest.java
index 9939425..981d983 100644
--- a/apm-sniffer/apm-sdk-plugin/undertow-plugins/undertow-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/undertow/v2x/ExecuteRootHandlerInterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/undertow-plugins/undertow-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/undertow/v2x/ExecuteRootHandlerInterceptorTest.java
@@ -18,6 +18,7 @@
 
 package org.apache.skywalking.apm.plugin.undertow.v2x;
 
+import org.apache.skywalking.apm.agent.core.conf.Config;
 import org.apache.skywalking.apm.agent.core.context.SW3CarrierItem;
 import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
 import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity;
@@ -36,6 +37,7 @@ import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
 import org.apache.skywalking.apm.agent.test.tools.SpanAssert;
 import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
 import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
@@ -89,6 +91,7 @@ public class ExecuteRootHandlerInterceptorTest {
 
     @Before
     public void setUp() throws Exception {
+        Config.Agent.ACTIVE_V1_HEADER = true;
         executeRootHandlerInterceptor = new ExecuteRootHandlerInterceptor();
         exchange = new HttpServerExchange(serverConnection, requestHeaders, responseHeaders, 0);
         exchange.setRequestURI("/test/testRequestURL");
@@ -96,8 +99,13 @@ public class ExecuteRootHandlerInterceptorTest {
         exchange.setDestinationAddress(new InetSocketAddress("localhost", 8080));
         exchange.setRequestScheme("http");
         exchange.setRequestMethod(HttpString.tryFromString("POST"));
-        arguments = new Object[]{httpHandler, exchange};
-        argumentType = new Class[]{httpHandler.getClass(), exchange.getClass()};
+        arguments = new Object[] {httpHandler, exchange};
+        argumentType = new Class[] {httpHandler.getClass(), exchange.getClass()};
+    }
+
+    @After
+    public void clear() {
+        Config.Agent.ACTIVE_V1_HEADER = false;
     }
 
     @Test
diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/opentracing/SkywalkingSpanActivationTest.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/opentracing/SkywalkingSpanActivationTest.java
index f6d700d..fb9d454 100644
--- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/opentracing/SkywalkingSpanActivationTest.java
+++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/opentracing/SkywalkingSpanActivationTest.java
@@ -16,31 +16,17 @@
  *
  */
 
-
 package org.apache.skywalking.apm.toolkit.activation.opentracing;
 
 import io.opentracing.Tracer;
 import io.opentracing.propagation.Format;
 import io.opentracing.propagation.TextMap;
 import io.opentracing.tag.Tags;
-
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-
-import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
-import org.apache.skywalking.apm.agent.test.tools.SegmentRefAssert;
-import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
-import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
-import org.apache.skywalking.apm.agent.test.tools.SpanAssert;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+import org.apache.skywalking.apm.agent.core.conf.Config;
 import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
 import org.apache.skywalking.apm.agent.core.context.SW3CarrierItem;
 import org.apache.skywalking.apm.agent.core.context.ids.ID;
@@ -48,7 +34,12 @@ import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
 import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
 import org.apache.skywalking.apm.agent.core.context.trace.TraceSegmentRef;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
 import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
+import org.apache.skywalking.apm.agent.test.tools.SegmentRefAssert;
+import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
+import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
+import org.apache.skywalking.apm.agent.test.tools.SpanAssert;
 import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
 import org.apache.skywalking.apm.toolkit.activation.opentracing.continuation.ActivateInterceptor;
 import org.apache.skywalking.apm.toolkit.activation.opentracing.continuation.ConstructorInterceptor;
@@ -62,12 +53,20 @@ import org.apache.skywalking.apm.toolkit.opentracing.SkywalkingContinuation;
 import org.apache.skywalking.apm.toolkit.opentracing.SkywalkingSpan;
 import org.apache.skywalking.apm.toolkit.opentracing.SkywalkingSpanBuilder;
 import org.apache.skywalking.apm.toolkit.opentracing.TextMapContext;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
 
+import static org.apache.skywalking.apm.agent.test.tools.SpanAssert.assertComponent;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.apache.skywalking.apm.agent.test.tools.SpanAssert.assertComponent;
 
 @RunWith(PowerMockRunner.class)
 @PowerMockRunnerDelegate(TracingSegmentRunner.class)
@@ -106,15 +105,16 @@ public class SkywalkingSpanActivationTest {
 
     @Before
     public void setUp() {
+        Config.Agent.ACTIVE_V1_HEADER = true;
         spanBuilder = new SkywalkingSpanBuilder("test").withTag(Tags.COMPONENT.getKey(), "test");
         constructorWithSpanBuilderInterceptor = new ConstructorWithSpanBuilderInterceptor();
         spanLogInterceptor = new SpanLogInterceptor();
-        logArgument = new Object[]{111111111L, event};
-        logArgumentType = new Class[]{long.class, HashMap.class};
+        logArgument = new Object[] {111111111L, event};
+        logArgumentType = new Class[] {long.class, HashMap.class};
 
         setOperationNameInterceptor = new SpanSetOperationNameInterceptor();
-        setOperationNameArgument = new Object[]{"testOperationName"};
-        setOperationNameArgumentType = new Class[]{String.class};
+        setOperationNameArgument = new Object[] {"testOperationName"};
+        setOperationNameArgumentType = new Class[] {String.class};
 
         spanFinishInterceptor = new SpanFinishInterceptor();
 
@@ -125,6 +125,11 @@ public class SkywalkingSpanActivationTest {
         activateInterceptor = new ActivateInterceptor();
     }
 
+    @After
+    public void clear() {
+        Config.Agent.ACTIVE_V1_HEADER = false;
+    }
+
     @Test
     public void testCreateLocalSpan() throws Throwable {
         startSpan();
@@ -167,7 +172,7 @@ public class SkywalkingSpanActivationTest {
     @Test
     public void testCreateExitSpanWithPeer() throws Throwable {
         spanBuilder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
-                .withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), "8080");
+            .withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), "8080");
         startSpan();
         stopSpan();
 
@@ -189,7 +194,7 @@ public class SkywalkingSpanActivationTest {
     @Test
     public void testInject() throws Throwable {
         spanBuilder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
-                .withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), 8080);
+            .withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), 8080);
         startSpan();
 
         final Map<String, String> values = new HashMap<String, String>();
@@ -207,7 +212,7 @@ public class SkywalkingSpanActivationTest {
         };
 
         injectInterceptor.afterMethod(enhancedInstance, null,
-                new Object[]{new TextMapContext(), Format.Builtin.TEXT_MAP, carrier}, null, null);
+            new Object[] {new TextMapContext(), Format.Builtin.TEXT_MAP, carrier}, null, null);
 
         String[] parts = values.get(SW3CarrierItem.HEADER_NAME).split("\\|", 8);
         Assert.assertEquals("0", parts[1]);
@@ -219,7 +224,7 @@ public class SkywalkingSpanActivationTest {
     @Test
     public void testExtractWithValidateContext() throws Throwable {
         spanBuilder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
-                .withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), 8080);
+            .withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), 8080);
         startSpan();
         final Map<String, String> values = new HashMap<String, String>();
         TextMap carrier = new TextMap() {
@@ -238,7 +243,7 @@ public class SkywalkingSpanActivationTest {
         values.put(SW3CarrierItem.HEADER_NAME, "1.343.222|3|1|1|#127.0.0.1:8080|#/portal/|#/testEntrySpan|434.12.12123");
 
         extractInterceptor.afterMethod(enhancedInstance, null,
-                new Object[]{Format.Builtin.TEXT_MAP, carrier}, new Class[]{}, null);
+            new Object[] {Format.Builtin.TEXT_MAP, carrier}, new Class[] {}, null);
         stopSpan();
 
         TraceSegment tracingSegment = assertTraceSemgnets();
@@ -256,7 +261,7 @@ public class SkywalkingSpanActivationTest {
     @Test
     public void testExtractWithInValidateContext() throws Throwable {
         spanBuilder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
-                .withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), 8080);
+            .withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), 8080);
         startSpan();
 
         final Map<String, String> values = new HashMap<String, String>();
@@ -276,7 +281,7 @@ public class SkywalkingSpanActivationTest {
         values.put(SW3CarrierItem.HEADER_NAME, "aaaaaaaa|3|#192.168.1.8:18002|#/portal/|#/testEntrySpan|1.234.444");
 
         extractInterceptor.afterMethod(enhancedInstance, null,
-                new Object[]{Format.Builtin.TEXT_MAP, carrier}, new Class[]{}, null);
+            new Object[] {Format.Builtin.TEXT_MAP, carrier}, new Class[] {}, null);
         stopSpan();
 
         TraceSegment tracingSegment = assertTraceSemgnets();
@@ -340,11 +345,11 @@ public class SkywalkingSpanActivationTest {
     }
 
     private void startSpan(MockEnhancedInstance enhancedInstance) throws Throwable {
-        constructorWithSpanBuilderInterceptor.onConstruct(enhancedInstance, new Object[]{spanBuilder});
+        constructorWithSpanBuilderInterceptor.onConstruct(enhancedInstance, new Object[] {spanBuilder});
         spanLogInterceptor.afterMethod(enhancedInstance, null, logArgument, logArgumentType, null);
 
         setOperationNameInterceptor.afterMethod(enhancedInstance, SkywalkingSpan.class.getMethod("setOperationName", String.class),
-                setOperationNameArgument, setOperationNameArgumentType, null);
+            setOperationNameArgument, setOperationNameArgumentType, null);
     }
 
     private class MockEnhancedInstance implements EnhancedInstance {
diff --git a/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/MultiScopesSpanListener.java b/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/MultiScopesSpanListener.java
index b6f2e85..e5434ae 100644
--- a/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/MultiScopesSpanListener.java
+++ b/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/MultiScopesSpanListener.java
@@ -175,7 +175,15 @@ public class MultiScopesSpanListener implements EntrySpanListener, ExitSpanListe
             sourceReceiver.receive(entrySourceBuilder.toEndpoint());
             sourceReceiver.receive(entrySourceBuilder.toServiceRelation());
             sourceReceiver.receive(entrySourceBuilder.toServiceInstanceRelation());
-            sourceReceiver.receive(entrySourceBuilder.toEndpointRelation());
+            EndpointRelation endpointRelation = entrySourceBuilder.toEndpointRelation();
+            /**
+             * Parent endpoint could be none, because in SkyWalking Cross Process Propagation Headers Protocol v2,
+             * endpoint in ref could be empty, based on that, endpoint relation maybe can't be established.
+             * So, I am making this source as optional.
+             */
+            if (endpointRelation != null) {
+                sourceReceiver.receive(endpointRelation);
+            }
         });
 
         exitSourceBuilders.forEach(exitSourceBuilder -> {
diff --git a/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/SourceBuilder.java b/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/SourceBuilder.java
index 6132458..2d39ecc 100644
--- a/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/SourceBuilder.java
+++ b/oap-server/server-receiver-plugin/skywalking-trace-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/trace/provider/parser/listener/endpoint/SourceBuilder.java
@@ -19,6 +19,7 @@
 package org.apache.skywalking.oap.server.receiver.trace.provider.parser.listener.endpoint;
 
 import lombok.*;
+import org.apache.skywalking.apm.util.StringUtil;
 import org.apache.skywalking.oap.server.core.source.*;
 
 /**
@@ -145,6 +146,9 @@ class SourceBuilder {
     }
 
     EndpointRelation toEndpointRelation() {
+        if (StringUtil.isEmpty(sourceEndpointName) || StringUtil.isEmpty(destEndpointName)) {
+            return null;
+        }
         EndpointRelation endpointRelation = new EndpointRelation();
         endpointRelation.setEndpointId(sourceEndpointId);
         endpointRelation.setEndpoint(sourceEndpointName);