package org.skywalking.apm.agent.core.context;
import org.skywalking.apm.util.StringUtil;
import org.skywalking.apm.trace.Span;
import org.skywalking.apm.trace.TraceId.DistributedTraceId;
import org.skywalking.apm.trace.TraceId.PropagatedTraceId;
import org.skywalking.apm.trace.TraceSegment;
import org.skywalking.apm.trace.tag.Tags;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
/**
* {@link ContextCarrier} is a data carrier of {@link TracerContext}.
* It holds the snapshot (current state) of {@link TracerContext}.
* <p>
* Created by wusheng on 2017/2/17.
*/
public class ContextCarrier implements Serializable {
/**
* {@link TraceSegment#traceSegmentId}
*/
private String traceSegmentId;
/**
* {@link Span#spanId}
*/
private int spanId = -1;
/**
* {@link TraceSegment#applicationCode}
*/
private String applicationCode;
/**
* {@link Tags#PEER_HOST}
*/
private String peerHost;
/**
* {@link DistributedTraceId}
*/
private List<DistributedTraceId> distributedTraceIds;
/**
* {@link TraceSegment#sampled}
*/
private boolean sampled;
/**
* Serialize this {@link ContextCarrier} to a {@link String},
* with '|' split.
*
* @return the serialization string.
*/
public String serialize() {
return StringUtil.join('|',
this.getTraceSegmentId(),
this.getSpanId() + "",
this.getApplicationCode(),
this.getPeerHost(),
this.serializeDistributedTraceIds(),
this.isSampled() ? "1" : "0");
}
/**
* Initialize fields with the given text.
*
* @param text carries {@link #traceSegmentId} and {@link #spanId}, with '|' split.
*/
public ContextCarrier deserialize(String text) {
if (text != null) {
String[] parts = text.split("\\|", 6);
if (parts.length == 6) {
try {
setSpanId(Integer.parseInt(parts[1]));
setTraceSegmentId(parts[0]);
setApplicationCode(parts[2]);
setPeerHost(parts[3]);
setDistributedTraceIds(deserializeDistributedTraceIds(parts[4]));
setSampled("1".equals(parts[5]));
} catch (NumberFormatException e) {
}
}
}
return this;
}
/**
* Make sure this {@link ContextCarrier} has been initialized.
*
* @return true for unbroken {@link ContextCarrier} or no-initialized. Otherwise, false;
*/
public boolean isValid() {
return !StringUtil.isEmpty(traceSegmentId)
&& getSpanId() > -1
&& !StringUtil.isEmpty(applicationCode)
&& !StringUtil.isEmpty(peerHost)
&& distributedTraceIds != null;
}
public String getTraceSegmentId() {
return traceSegmentId;
}
public int getSpanId() {
return spanId;
}
public void setTraceSegmentId(String traceSegmentId) {
this.traceSegmentId = traceSegmentId;
}
public void setSpanId(int spanId) {
this.spanId = spanId;
}
public String getApplicationCode() {
return applicationCode;
}
public void setApplicationCode(String applicationCode) {
this.applicationCode = applicationCode;
}
public String getPeerHost() {
return peerHost;
}
public void setPeerHost(String peerHost) {
this.peerHost = peerHost;
}
public List<DistributedTraceId> getDistributedTraceIds() {
return distributedTraceIds;
}
public boolean isSampled() {
return sampled;
}
public void setSampled(boolean sampled) {
this.sampled = sampled;
}
public void setDistributedTraceIds(List<DistributedTraceId> distributedTraceIds) {
this.distributedTraceIds = distributedTraceIds;
}
/**
* Serialize {@link #distributedTraceIds} to a string, with ',' split.
*
* @return string, represents all {@link DistributedTraceId}
*/
private String serializeDistributedTraceIds() {
StringBuilder traceIdString = new StringBuilder();
if (distributedTraceIds != null) {
boolean first = true;
for (DistributedTraceId distributedTraceId : distributedTraceIds) {
if (first) {
first = false;
} else {
traceIdString.append(",");
}
traceIdString.append(distributedTraceId.get());
}
}
return traceIdString.toString();
}
/**
* Deserialize {@link #distributedTraceIds} from a text, whith
*
* @param text
* @return
*/
private List<DistributedTraceId> deserializeDistributedTraceIds(String text) {
if (StringUtil.isEmpty(text)) {
return null;
}
String[] propagationTraceIdValues = text.split(",");
List<DistributedTraceId> traceIds = new LinkedList<DistributedTraceId>();
for (String propagationTraceIdValue : propagationTraceIdValues) {
traceIds.add(new PropagatedTraceId(propagationTraceIdValue));
}
return traceIds;
}
}