Support v3 extension header (#4666)
* support v3 extension header Co-authored-by: Mrproliu <mrproliu@lagou.com> Co-authored-by: 吴晟 Wu Sheng <wu.sheng@foxmail.com>
This commit is contained in:
parent
418bdff277
commit
7d1fdd3ea8
|
|
@ -42,9 +42,11 @@ public class ContextCarrier implements Serializable {
|
|||
private String addressUsedAtClient;
|
||||
|
||||
private CorrelationContext correlationContext = new CorrelationContext();
|
||||
private ExtensionContext extensionContext = new ExtensionContext();
|
||||
|
||||
public CarrierItem items() {
|
||||
SW8CorrelationCarrierItem sw8CorrelationCarrierItem = new SW8CorrelationCarrierItem(correlationContext, null);
|
||||
SW8ExtensionCarrierItem sw8ExtensionCarrierItem = new SW8ExtensionCarrierItem(extensionContext, null);
|
||||
SW8CorrelationCarrierItem sw8CorrelationCarrierItem = new SW8CorrelationCarrierItem(correlationContext, sw8ExtensionCarrierItem);
|
||||
SW8CarrierItem sw8CarrierItem = new SW8CarrierItem(this, sw8CorrelationCarrierItem);
|
||||
return new CarrierItemHead(sw8CarrierItem);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,17 +33,20 @@ public class ContextSnapshot {
|
|||
private String parentEndpoint;
|
||||
|
||||
private CorrelationContext correlationContext;
|
||||
private ExtensionContext extensionContext;
|
||||
|
||||
ContextSnapshot(String traceSegmentId,
|
||||
int spanId,
|
||||
DistributedTraceId primaryTraceId,
|
||||
String parentEndpoint,
|
||||
CorrelationContext correlationContext) {
|
||||
CorrelationContext correlationContext,
|
||||
ExtensionContext extensionContext) {
|
||||
this.traceSegmentId = traceSegmentId;
|
||||
this.spanId = spanId;
|
||||
this.traceId = primaryTraceId;
|
||||
this.parentEndpoint = parentEndpoint;
|
||||
this.correlationContext = correlationContext.clone();
|
||||
this.extensionContext = extensionContext.clone();
|
||||
}
|
||||
|
||||
public boolean isFromCurrent() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* 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 org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Extension context, It provides the interaction capabilities between the agents
|
||||
* deployed in upstream and downstream services.
|
||||
*/
|
||||
public class ExtensionContext {
|
||||
|
||||
/**
|
||||
* Tracing Mode. If true means represents all spans generated in this context should skip analysis.
|
||||
*/
|
||||
private boolean skipAnalysis;
|
||||
|
||||
/**
|
||||
* Serialize this {@link ExtensionContext} to a {@link String}
|
||||
*
|
||||
* @return the serialization string.
|
||||
*/
|
||||
String serialize() {
|
||||
return skipAnalysis ? "1" : "0";
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize data from {@link String}
|
||||
*/
|
||||
void deserialize(String value) {
|
||||
this.skipAnalysis = Objects.equals(value, "1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare for the cross-process propagation.
|
||||
*/
|
||||
void inject(ContextCarrier carrier) {
|
||||
carrier.getExtensionContext().skipAnalysis = this.skipAnalysis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extra the {@link ContextCarrier#getExtensionContext()} into this context.
|
||||
*/
|
||||
void extract(ContextCarrier carrier) {
|
||||
this.skipAnalysis = carrier.getExtensionContext().skipAnalysis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the tracing span.
|
||||
*/
|
||||
void handle(AbstractSpan span) {
|
||||
if (this.skipAnalysis) {
|
||||
span.skipAnalysis();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone the context data, work for capture to cross-thread.
|
||||
*/
|
||||
public ExtensionContext clone() {
|
||||
final ExtensionContext context = new ExtensionContext();
|
||||
context.skipAnalysis = this.skipAnalysis;
|
||||
return context;
|
||||
}
|
||||
|
||||
void continued(ContextSnapshot snapshot) {
|
||||
this.skipAnalysis = snapshot.getExtensionContext().skipAnalysis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ExtensionContext that = (ExtensionContext) o;
|
||||
return skipAnalysis == that.skipAnalysis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(skipAnalysis);
|
||||
}
|
||||
}
|
||||
|
|
@ -33,12 +33,14 @@ public class IgnoredTracerContext implements AbstractTracerContext {
|
|||
private static final NoopSpan NOOP_SPAN = new NoopSpan();
|
||||
|
||||
private final CorrelationContext correlationContext;
|
||||
private final ExtensionContext extensionContext;
|
||||
|
||||
private int stackDepth;
|
||||
|
||||
public IgnoredTracerContext() {
|
||||
this.stackDepth = 0;
|
||||
this.correlationContext = new CorrelationContext();
|
||||
this.extensionContext = new ExtensionContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -53,7 +55,7 @@ public class IgnoredTracerContext implements AbstractTracerContext {
|
|||
|
||||
@Override
|
||||
public ContextSnapshot capture() {
|
||||
return new ContextSnapshot(null, -1, null, null, correlationContext);
|
||||
return new ContextSnapshot(null, -1, null, null, correlationContext, extensionContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.agent.core.context;
|
||||
|
||||
public class SW8ExtensionCarrierItem extends CarrierItem {
|
||||
public static final String HEADER_NAME = "sw8-x";
|
||||
private final ExtensionContext extensionContext;
|
||||
|
||||
public SW8ExtensionCarrierItem(ExtensionContext extensionContext, CarrierItem next) {
|
||||
super(HEADER_NAME, extensionContext.serialize(), next);
|
||||
this.extensionContext = extensionContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeadValue(String headValue) {
|
||||
this.extensionContext.deserialize(headValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -111,6 +111,7 @@ public class TracingContext implements AbstractTracerContext {
|
|||
private final ProfileStatusReference profileStatus;
|
||||
|
||||
private final CorrelationContext correlationContext;
|
||||
private final ExtensionContext extensionContext;
|
||||
|
||||
/**
|
||||
* Initialize all fields with default value.
|
||||
|
|
@ -134,6 +135,7 @@ public class TracingContext implements AbstractTracerContext {
|
|||
this, segment.getTraceSegmentId(), firstOPName);
|
||||
|
||||
this.correlationContext = new CorrelationContext();
|
||||
this.extensionContext = new ExtensionContext();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -177,6 +179,7 @@ public class TracingContext implements AbstractTracerContext {
|
|||
carrier.setAddressUsedAtClient(peer);
|
||||
|
||||
this.correlationContext.inject(carrier);
|
||||
this.extensionContext.inject(carrier);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -195,6 +198,8 @@ public class TracingContext implements AbstractTracerContext {
|
|||
}
|
||||
|
||||
this.correlationContext.extract(carrier);
|
||||
this.extensionContext.extract(carrier);
|
||||
this.extensionContext.handle(span);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -209,7 +214,8 @@ public class TracingContext implements AbstractTracerContext {
|
|||
activeSpan().getSpanId(),
|
||||
getPrimaryTraceId(),
|
||||
first().getOperationName(),
|
||||
this.correlationContext
|
||||
this.correlationContext,
|
||||
this.extensionContext
|
||||
);
|
||||
|
||||
return snapshot;
|
||||
|
|
@ -228,6 +234,8 @@ public class TracingContext implements AbstractTracerContext {
|
|||
this.activeSpan().ref(segmentRef);
|
||||
this.segment.relatedGlobalTraces(snapshot.getTraceId());
|
||||
this.correlationContext.continued(snapshot);
|
||||
this.extensionContext.continued(snapshot);
|
||||
this.extensionContext.handle(this.activeSpan());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -529,6 +537,7 @@ public class TracingContext implements AbstractTracerContext {
|
|||
firstSpan = span;
|
||||
}
|
||||
activeSpanStack.addLast(span);
|
||||
this.extensionContext.handle(span);
|
||||
return span;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,4 +119,9 @@ public interface AbstractSpan extends AsyncSpan {
|
|||
* @return true if the span's owner(tracing context main thread) is been profiled.
|
||||
*/
|
||||
boolean isProfiling();
|
||||
|
||||
/**
|
||||
* Should skip analysis in the backend.
|
||||
*/
|
||||
void skipAnalysis();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,11 @@ public abstract class AbstractTracingSpan implements AbstractSpan {
|
|||
*/
|
||||
protected List<TraceSegmentRef> refs;
|
||||
|
||||
/**
|
||||
* Tracing Mode. If true means represents all spans generated in this context should skip analysis.
|
||||
*/
|
||||
protected boolean skipAnalysis;
|
||||
|
||||
protected AbstractTracingSpan(int spanId, int parentSpanId, String operationName, TracingContext owner) {
|
||||
this.operationName = operationName;
|
||||
this.spanId = spanId;
|
||||
|
|
@ -246,6 +251,7 @@ public abstract class AbstractTracingSpan implements AbstractSpan {
|
|||
spanBuilder.setStartTime(startTime);
|
||||
spanBuilder.setEndTime(endTime);
|
||||
spanBuilder.setOperationName(operationName);
|
||||
spanBuilder.setSkipAnalysis(skipAnalysis);
|
||||
if (isEntry()) {
|
||||
spanBuilder.setSpanType(SpanType.Entry);
|
||||
} else if (isExit()) {
|
||||
|
|
@ -317,4 +323,9 @@ public abstract class AbstractTracingSpan implements AbstractSpan {
|
|||
public boolean isProfiling() {
|
||||
return this.owner.profileStatus().isProfiling();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skipAnalysis() {
|
||||
this.skipAnalysis = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,6 +119,10 @@ public class NoopSpan implements AbstractSpan {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skipAnalysis() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSpan prepareForAsync() {
|
||||
return this;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ public class ContextCarrierV3HeaderTest {
|
|||
next.setHeadValue("1-My40LjU=-MS4yLjM=-4-c2VydmljZQ==-aW5zdGFuY2U=-L2FwcA==-MTI3LjAuMC4xOjgwODA=");
|
||||
} else if (next.getHeadKey().equals(SW8CorrelationCarrierItem.HEADER_NAME)) {
|
||||
next.setHeadValue("dGVzdA==:dHJ1ZQ==");
|
||||
} else if (next.getHeadKey().equals(SW8ExtensionCarrierItem.HEADER_NAME)) {
|
||||
next.setHeadValue("1");
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown Header: " + next.getHeadKey());
|
||||
}
|
||||
|
|
@ -61,6 +63,8 @@ public class ContextCarrierV3HeaderTest {
|
|||
|
||||
contextCarrier.getCorrelationContext().put("test", "true");
|
||||
|
||||
contextCarrier.getExtensionContext().deserialize("1");
|
||||
|
||||
CarrierItem next = contextCarrier.items();
|
||||
while (next.hasNext()) {
|
||||
next = next.next();
|
||||
|
|
@ -73,6 +77,8 @@ public class ContextCarrierV3HeaderTest {
|
|||
* "test:true"
|
||||
*/
|
||||
Assert.assertEquals("dGVzdA==:dHJ1ZQ==", next.getHeadValue());
|
||||
} else if (next.getHeadKey().equals(SW8ExtensionCarrierItem.HEADER_NAME)) {
|
||||
Assert.assertEquals("1", next.getHeadValue());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown Header: " + next.getHeadKey());
|
||||
}
|
||||
|
|
@ -85,6 +91,8 @@ public class ContextCarrierV3HeaderTest {
|
|||
Assert.assertEquals("1-My40LjU=-MS4yLjM=-4-c2VydmljZQ==-aW5zdGFuY2U=-L2FwcA==-MTI3LjAuMC4xOjgwODA=", next.getHeadValue());
|
||||
} else if (next.getHeadKey().equals(SW8CorrelationCarrierItem.HEADER_NAME)) {
|
||||
Assert.assertEquals("dGVzdA==:dHJ1ZQ==", next.getHeadValue());
|
||||
} else if (next.getHeadKey().equals(SW8ExtensionCarrierItem.HEADER_NAME)) {
|
||||
Assert.assertEquals("1", next.getHeadValue());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown Header: " + next.getHeadKey());
|
||||
}
|
||||
|
|
@ -109,16 +117,20 @@ public class ContextCarrierV3HeaderTest {
|
|||
contextCarrier.setParentEndpoint("/app");
|
||||
|
||||
contextCarrier.getCorrelationContext().put("test", "true");
|
||||
contextCarrier.getExtensionContext().deserialize("1");
|
||||
|
||||
CarrierItem next = contextCarrier.items();
|
||||
String sw6HeaderValue = null;
|
||||
String correlationHeaderValue = null;
|
||||
String extensionHeaderValue = null;
|
||||
while (next.hasNext()) {
|
||||
next = next.next();
|
||||
if (next.getHeadKey().equals(SW8CarrierItem.HEADER_NAME)) {
|
||||
sw6HeaderValue = next.getHeadValue();
|
||||
} else if (next.getHeadKey().equals(SW8CorrelationCarrierItem.HEADER_NAME)) {
|
||||
correlationHeaderValue = next.getHeadValue();
|
||||
} else if (next.getHeadKey().equals(SW8ExtensionCarrierItem.HEADER_NAME)) {
|
||||
extensionHeaderValue = next.getHeadValue();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown Header: " + next.getHeadKey());
|
||||
}
|
||||
|
|
@ -132,6 +144,8 @@ public class ContextCarrierV3HeaderTest {
|
|||
next.setHeadValue(sw6HeaderValue);
|
||||
} else if (next.getHeadKey().equals(SW8CorrelationCarrierItem.HEADER_NAME)) {
|
||||
next.setHeadValue(correlationHeaderValue);
|
||||
} else if (next.getHeadKey().equals(SW8ExtensionCarrierItem.HEADER_NAME)) {
|
||||
next.setHeadValue(extensionHeaderValue);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown Header: " + next.getHeadKey());
|
||||
}
|
||||
|
|
@ -146,5 +160,6 @@ public class ContextCarrierV3HeaderTest {
|
|||
Assert.assertEquals(contextCarrier.getParentServiceInstance(), contextCarrier2.getParentServiceInstance());
|
||||
Assert.assertEquals(contextCarrier.getParentEndpoint(), contextCarrier2.getParentEndpoint());
|
||||
Assert.assertEquals(contextCarrier.getCorrelationContext(), contextCarrier2.getCorrelationContext());
|
||||
Assert.assertEquals(contextCarrier.getExtensionContext(), contextCarrier2.getExtensionContext());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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 org.apache.skywalking.apm.agent.core.context.trace.NoopSpan;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
public class ExtensionContextTest {
|
||||
|
||||
@Test
|
||||
public void testSerialize() {
|
||||
final ExtensionContext context = new ExtensionContext();
|
||||
Assert.assertEquals(context.serialize(), "0");
|
||||
|
||||
context.deserialize("1");
|
||||
Assert.assertEquals(context.serialize(), "1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeSerialize() {
|
||||
final ExtensionContext context = new ExtensionContext();
|
||||
context.deserialize("");
|
||||
Assert.assertEquals(context.serialize(), "0");
|
||||
|
||||
context.deserialize("0");
|
||||
Assert.assertEquals(context.serialize(), "0");
|
||||
|
||||
context.deserialize("test");
|
||||
Assert.assertEquals(context.serialize(), "0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClone() {
|
||||
final ExtensionContext context = new ExtensionContext();
|
||||
Assert.assertEquals(context, context.clone());
|
||||
|
||||
context.deserialize("1");
|
||||
Assert.assertEquals(context, context.clone());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandle() {
|
||||
final ExtensionContext context = new ExtensionContext();
|
||||
context.deserialize("1");
|
||||
NoopSpan span = Mockito.mock(NoopSpan.class);
|
||||
context.handle(span);
|
||||
verify(span, times(1)).skipAnalysis();
|
||||
|
||||
context.deserialize("0");
|
||||
span = Mockito.mock(NoopSpan.class);
|
||||
context.handle(span);
|
||||
verify(span, times(0)).skipAnalysis();
|
||||
}
|
||||
}
|
||||
|
|
@ -133,7 +133,7 @@ public class HttpClientExecuteInterceptorTest {
|
|||
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
|
||||
assertHttpSpan(spans.get(0));
|
||||
verify(request, times(2)).setHeader(anyString(), anyString());
|
||||
verify(request, times(3)).setHeader(anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -154,7 +154,7 @@ public class HttpClientExecuteInterceptorTest {
|
|||
|
||||
assertHttpSpan(spans.get(0));
|
||||
assertThat(SpanHelper.getErrorOccurred(spans.get(0)), is(true));
|
||||
verify(request, times(2)).setHeader(anyString(), anyString());
|
||||
verify(request, times(3)).setHeader(anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -172,7 +172,7 @@ public class HttpClientExecuteInterceptorTest {
|
|||
assertHttpSpan(span);
|
||||
assertThat(SpanHelper.getErrorOccurred(span), is(true));
|
||||
assertHttpSpanErrorLog(SpanHelper.getLogs(span));
|
||||
verify(request, times(2)).setHeader(anyString(), anyString());
|
||||
verify(request, times(3)).setHeader(anyString(), anyString());
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -202,7 +202,7 @@ public class HttpClientExecuteInterceptorTest {
|
|||
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
|
||||
assertHttpSpan(spans.get(0));
|
||||
verify(request, times(2)).setHeader(anyString(), anyString());
|
||||
verify(request, times(3)).setHeader(anyString(), anyString());
|
||||
}
|
||||
|
||||
private void assertHttpSpanErrorLog(List<LogDataEntity> logs) {
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ public class HttpAsyncClientInterceptorTest {
|
|||
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(findNeedSegemnt());
|
||||
assertHttpSpan(spans.get(0));
|
||||
verify(requestWrapper, times(2)).setHeader(anyString(), anyString());
|
||||
verify(requestWrapper, times(3)).setHeader(anyString(), anyString());
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ public class MotanConsumerInterceptorTest {
|
|||
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
|
||||
assertMotanConsumerSpan(spans.get(0));
|
||||
verify(request, times(2)).setAttachment(anyString(), anyString());
|
||||
verify(request, times(3)).setAttachment(anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -111,7 +111,7 @@ public class MotanConsumerInterceptorTest {
|
|||
|
||||
private void assertTraceSegmentWhenOccurException(AbstractTracingSpan tracingSpan) {
|
||||
assertMotanConsumerSpan(tracingSpan);
|
||||
verify(request, times(2)).setAttachment(anyString(), anyString());
|
||||
verify(request, times(3)).setAttachment(anyString(), anyString());
|
||||
List<LogDataEntity> logDataEntities = SpanHelper.getLogs(tracingSpan);
|
||||
assertThat(logDataEntities.size(), is(1));
|
||||
SpanAssert.assertException(logDataEntities.get(0), RuntimeException.class);
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ public class ProducerOperationHandlerInterceptorTest {
|
|||
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
|
||||
assertCombSpan(spans.get(0));
|
||||
verify(invocation, times(2)).getContext();
|
||||
verify(invocation, times(3)).getContext();
|
||||
}
|
||||
|
||||
private void assertCombSpan(AbstractTracingSpan span) {
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ public class TransportClientHandlerInterceptorTest {
|
|||
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
|
||||
assertCombSpan(spans.get(0));
|
||||
verify(invocation, times(2)).getContext();
|
||||
verify(invocation, times(3)).getContext();
|
||||
}
|
||||
|
||||
private void assertCombSpan(AbstractTracingSpan span) {
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ public class ProducerOperationHandlerInterceptorTest {
|
|||
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
|
||||
assertCombSpan(spans.get(0));
|
||||
verify(invocation, times(2)).getContext();
|
||||
verify(invocation, times(3)).getContext();
|
||||
}
|
||||
|
||||
private void assertCombSpan(AbstractTracingSpan span) {
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ public class TransportClientHandlerInterceptorTest {
|
|||
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
|
||||
assertCombSpan(spans.get(0));
|
||||
verify(invocation, times(2)).getContext();
|
||||
verify(invocation, times(3)).getContext();
|
||||
}
|
||||
|
||||
private void assertCombSpan(AbstractTracingSpan span) {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public enum MockContextSnapshot {
|
|||
distributedTraceIds.add(new NewDistributedTraceId());
|
||||
|
||||
contextSnapshot = new ContextSnapshot(
|
||||
"1, 2, 3", 1, new NewDistributedTraceId(), "/for-test-entryOperationName", new CorrelationContext());
|
||||
"1, 2, 3", 1, new NewDistributedTraceId(), "/for-test-entryOperationName", new CorrelationContext(), new ExtensionContext());
|
||||
}
|
||||
|
||||
public ContextSnapshot mockContextSnapshot() {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<agent-test-tools.version>1f009d692b99896c08cf9f26440f92287f0364e7</agent-test-tools.version>
|
||||
<agent-test-tools.version>da281e9c0340ca68f9bf25512701cb463aa20f12</agent-test-tools.version>
|
||||
<agent-test-tools.workingDirectory>${project.basedir}/target/agent-test-tools</agent-test-tools.workingDirectory>
|
||||
<agent-test-tools.repos>https://github.com/apache/skywalking-agent-test-tool.git</agent-test-tools.repos>
|
||||
</properties>
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ exec /var/run/${SCENARIO_NAME}/${SCENARIO_START_SCRIPT} 1>/dev/null &
|
|||
healthCheck ${SCENARIO_HEALTH_CHECK_URL}
|
||||
|
||||
echo "To visit entry service"
|
||||
curl -s --max-time 3 ${SCENARIO_ENTRY_SERVICE}
|
||||
`echo curl ${SCENARIO_EXTEND_ENTRY_HEADER} -s --max-time 3 ${SCENARIO_ENTRY_SERVICE}`
|
||||
sleep 5
|
||||
|
||||
echo "To receive actual data"
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import org.apache.skywalking.plugin.test.helper.exception.ConfigureFileNotFoundE
|
|||
import org.apache.skywalking.plugin.test.helper.vo.CaseConfiguration;
|
||||
import org.apache.skywalking.plugin.test.helper.vo.DependencyComponent;
|
||||
import org.apache.skywalking.plugin.test.helper.vo.DockerService;
|
||||
import org.apache.skywalking.plugin.test.helper.vo.RequestHeader;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
public class ConfigurationImpl implements IConfiguration {
|
||||
|
|
@ -183,6 +184,7 @@ public class ConfigurationImpl implements IConfiguration {
|
|||
|
||||
root.put("network_name", dockerNetworkName());
|
||||
root.put("services", convertDockerServices(scenarioVersion(), caseConfiguration().getDependencies()));
|
||||
root.put("extend_entry_header", extendEntryHeader());
|
||||
|
||||
root.put("docker_compose_file", outputDir() + File.separator + "docker-compose.yml");
|
||||
root.put("build_id", dockerImageVersion());
|
||||
|
|
@ -206,6 +208,19 @@ public class ConfigurationImpl implements IConfiguration {
|
|||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String extendEntryHeader() {
|
||||
final List<RequestHeader> headers = this.configuration.getExtendEntryHeader();
|
||||
if (headers == null || headers.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder headerString = new StringBuilder("\"");
|
||||
for (RequestHeader header : headers) {
|
||||
headerString.append(" -H ").append(header.getKey()).append(":").append(header.getValue()).append(" ");
|
||||
}
|
||||
return headerString.append("\"").toString();
|
||||
}
|
||||
|
||||
protected List<DockerService> convertDockerServices(final String version,
|
||||
Map<String, DependencyComponent> componentMap) {
|
||||
final ArrayList<DockerService> services = Lists.newArrayList();
|
||||
|
|
|
|||
|
|
@ -57,4 +57,6 @@ public interface IConfiguration {
|
|||
String jacocoHome();
|
||||
|
||||
Map<String, Object> toMap();
|
||||
|
||||
String extendEntryHeader();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,4 +37,5 @@ public class CaseConfiguration {
|
|||
private List<String> depends_on;
|
||||
private String runningMode;
|
||||
private String withPlugins;
|
||||
private List<RequestHeader> extendEntryHeader;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.plugin.test.helper.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Extension header when starting request to entry service.
|
||||
*/
|
||||
@Data
|
||||
public class RequestHeader {
|
||||
private String key;
|
||||
private String value;
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ docker run \
|
|||
</#if>
|
||||
--env SCENARIO_ENTRY_SERVICE=${entry_service} \
|
||||
--env SCENARIO_HEALTH_CHECK_URL=${health_check} \
|
||||
--env SCENARIO_EXTEND_ENTRY_HEADER=${extend_entry_header} \
|
||||
<#if catalina_opts??>
|
||||
--env CATALINA_OPTS=${catalina_opts} \
|
||||
</#if>
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ services:
|
|||
- SCENARIO_VERSION=${scenario_version}
|
||||
- SCENARIO_ENTRY_SERVICE=${entry_service}
|
||||
- SCENARIO_HEALTH_CHECK_URL=${health_check}
|
||||
- SCENARIO_EXTEND_ENTRY_HEADER=${extend_entry_header}
|
||||
volumes:
|
||||
- ${agent_home}:/usr/local/skywalking/scenario/agent
|
||||
- ${scenario_home}:/usr/local/skywalking/scenario
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ segmentItems:
|
|||
peer: ''
|
||||
tags:
|
||||
- {key: key, value: value}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- operationName: test.org.apache.skywalking.apm.testcase.toolkit.controller.TestService.testInfo(java.lang.String)
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
|
|
@ -50,7 +50,7 @@ segmentItems:
|
|||
- {key: message, value: TestInfoMsg}
|
||||
tags:
|
||||
- {key: testTag, value: testInfoParam}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- operationName: test.org.apache.skywalking.apm.testcase.toolkit.controller.TestService.testDebug()
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
|
|
@ -66,11 +66,11 @@ segmentItems:
|
|||
- logEvent:
|
||||
- {key: event, value: debug}
|
||||
- {key: message, value: TestDebugMsg}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- {operationName: test.org.apache.skywalking.apm.testcase.toolkit.controller.TestService.testError(),
|
||||
operationId: 0, parentSpanId: 0, spanId: 4, spanLayer: Unknown, startTime: nq
|
||||
0, endTime: nq 0, componentId: 0, isError: true, spanType: Local, peer: '',
|
||||
skipAnalysis: 'false'}
|
||||
skipAnalysis: 'true'}
|
||||
- operationName: test.org.apache.skywalking.apm.testcase.toolkit.controller.TestService.testErrorMsg()
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
|
|
@ -86,7 +86,7 @@ segmentItems:
|
|||
- logEvent:
|
||||
- {key: event, value: error}
|
||||
- {key: message, value: TestErrorMsg}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- operationName: test.org.apache.skywalking.apm.testcase.toolkit.controller.TestService.testErrorThrowable()
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
|
|
@ -104,7 +104,7 @@ segmentItems:
|
|||
- {key: error.kind, value: java.lang.RuntimeException}
|
||||
- {key: message, value: Test-Exception}
|
||||
- {key: stack, value: not null}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- operationName: test.org.apache.skywalking.apm.testcase.toolkit.controller.TestService.testTagAnnotation(java.lang.String,java.lang.String)
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
|
|
@ -119,7 +119,7 @@ segmentItems:
|
|||
tags:
|
||||
- {key: p1, value: testTagAnnotationParam1}
|
||||
- {key: p2, value: testTagAnnotationParam2}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- operationName: test.org.apache.skywalking.apm.testcase.toolkit.controller.TestService.testTagAnnotationReturnInfo(java.lang.String,java.lang.Integer)
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
|
|
@ -133,7 +133,7 @@ segmentItems:
|
|||
peer: ''
|
||||
tags:
|
||||
- {key: username, value: zhangsan}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- operationName: /case/tool-kit
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
|
|
@ -148,7 +148,11 @@ segmentItems:
|
|||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/apm-toolkit-trace-scenario/case/tool-kit'}
|
||||
- {key: http.method, value: GET}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
refs:
|
||||
- {parentEndpoint: /app, networkAddress: '127.0.0.1:8080', refType: CrossProcess,
|
||||
parentSpanId: 4, parentTraceSegmentId: 1.2.3, parentServiceInstance: instance,
|
||||
parentService: service, traceId: 3.4.5}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /case/asyncVisit/callable
|
||||
|
|
@ -171,7 +175,7 @@ segmentItems:
|
|||
networkAddress: 'localhost:8080', refType: CrossProcess, parentSpanId: 1,
|
||||
parentTraceSegmentId: not null, parentServiceInstance: not null, parentService: not
|
||||
null, traceId: not null}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /apm-toolkit-trace-scenario/case/asyncVisit/runnable
|
||||
|
|
@ -188,7 +192,7 @@ segmentItems:
|
|||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/apm-toolkit-trace-scenario/case/asyncVisit/runnable'}
|
||||
- {key: http.method, value: GET}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- operationName: Thread/org.apache.skywalking.apm.toolkit.trace.RunnableWrapper/run
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
|
|
@ -204,7 +208,7 @@ segmentItems:
|
|||
- {parentEndpoint: /case/tool-kit, networkAddress: '', refType: CrossThread,
|
||||
parentSpanId: 0, parentTraceSegmentId: not null, parentServiceInstance: not
|
||||
null, parentService: not null, traceId: not null}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /apm-toolkit-trace-scenario/case/asyncVisit/callable
|
||||
|
|
@ -221,7 +225,7 @@ segmentItems:
|
|||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/apm-toolkit-trace-scenario/case/asyncVisit/callable'}
|
||||
- {key: http.method, value: GET}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- operationName: Thread/org.apache.skywalking.apm.toolkit.trace.CallableWrapper/call
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
|
|
@ -237,7 +241,7 @@ segmentItems:
|
|||
- {parentEndpoint: /case/tool-kit, networkAddress: '', refType: CrossThread,
|
||||
parentSpanId: 0, parentTraceSegmentId: not null, parentServiceInstance: not
|
||||
null, parentService: not null, traceId: not null}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /case/asyncVisit/runnable
|
||||
|
|
@ -260,7 +264,7 @@ segmentItems:
|
|||
networkAddress: 'localhost:8080', refType: CrossProcess, parentSpanId: 1,
|
||||
parentTraceSegmentId: not null, parentServiceInstance: not null, parentService: not
|
||||
null, traceId: not null}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /apm-toolkit-trace-scenario/case/asyncVisit/supplier
|
||||
|
|
@ -277,7 +281,7 @@ segmentItems:
|
|||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/apm-toolkit-trace-scenario/case/asyncVisit/supplier'}
|
||||
- {key: http.method, value: GET}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- operationName: Thread/org.apache.skywalking.apm.toolkit.trace.SupplierWrapper/get
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
|
|
@ -293,7 +297,7 @@ segmentItems:
|
|||
- {parentEndpoint: /case/tool-kit, networkAddress: '', refType: CrossThread,
|
||||
parentSpanId: 0, parentTraceSegmentId: not null, parentServiceInstance: not
|
||||
null, parentService: not null, traceId: not null}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /case/asyncVisit/supplier
|
||||
|
|
@ -316,4 +320,4 @@ segmentItems:
|
|||
networkAddress: 'localhost:8080', refType: CrossProcess, parentSpanId: 1,
|
||||
parentTraceSegmentId: not null, parentServiceInstance: not null, parentService: not
|
||||
null, traceId: not null}
|
||||
skipAnalysis: 'false'
|
||||
skipAnalysis: 'true'
|
||||
|
|
|
|||
|
|
@ -18,3 +18,8 @@ type: jvm
|
|||
entryService: http://localhost:8080/apm-toolkit-trace-scenario/case/tool-kit
|
||||
healthCheck: http://localhost:8080/apm-toolkit-trace-scenario/case/healthCheck
|
||||
startScript: ./bin/startup.sh
|
||||
extendEntryHeader:
|
||||
- key: sw8-x
|
||||
value: 1
|
||||
- key: sw8
|
||||
value: 1-My40LjU=-MS4yLjM=-4-c2VydmljZQ==-aW5zdGFuY2U=-L2FwcA==-MTI3LjAuMC4xOjgwODA=
|
||||
|
|
|
|||
Loading…
Reference in New Issue