diff --git a/src/API/Trace/Propagation/TraceContextPropagator.php b/src/API/Trace/Propagation/TraceContextPropagator.php index 5814d642c..a91c91db5 100644 --- a/src/API/Trace/Propagation/TraceContextPropagator.php +++ b/src/API/Trace/Propagation/TraceContextPropagator.php @@ -10,6 +10,7 @@ use OpenTelemetry\API\Trace\Span; use OpenTelemetry\API\Trace\SpanContext; use OpenTelemetry\API\Trace\SpanContextInterface; +use OpenTelemetry\API\Trace\SpanContextValidator; use OpenTelemetry\API\Trace\TraceState; use OpenTelemetry\Context\Context; use OpenTelemetry\Context\ContextInterface; @@ -114,10 +115,10 @@ private static function extractImpl($carrier, PropagationGetterInterface $getter * - Version is invalid (not 2 char hex or 'ff') * - Trace version, trace ID, span ID or trace flag are invalid */ - if (!SpanContext::isValidTraceVersion($version) - || !SpanContext::isValidTraceId($traceId) - || !SpanContext::isValidSpanId($spanId) - || !SpanContext::isValidTraceFlag($traceFlags) + if (!TraceContextValidator::isValidTraceVersion($version) + || !SpanContextValidator::isValidTraceId($traceId) + || !SpanContextValidator::isValidSpanId($spanId) + || !TraceContextValidator::isValidTraceFlag($traceFlags) ) { return SpanContext::getInvalid(); } @@ -130,7 +131,7 @@ private static function extractImpl($carrier, PropagationGetterInterface $getter // Only the sampled flag is extracted from the traceFlags (00000001) $convertedTraceFlags = hexdec($traceFlags); - $isSampled = ($convertedTraceFlags & SpanContext::SAMPLED_FLAG) === SpanContext::SAMPLED_FLAG; + $isSampled = ($convertedTraceFlags & SpanContextInterface::TRACE_FLAG_SAMPLED) === SpanContextInterface::TRACE_FLAG_SAMPLED; // Tracestate = 'Vendor1=Value1,...,VendorN=ValueN' $rawTracestate = $getter->get($carrier, self::TRACESTATE); diff --git a/src/API/Trace/Propagation/TraceContextValidator.php b/src/API/Trace/Propagation/TraceContextValidator.php new file mode 100644 index 000000000..428264cdc --- /dev/null +++ b/src/API/Trace/Propagation/TraceContextValidator.php @@ -0,0 +1,31 @@ +isValid=false; } $this->traceId = $traceId; $this->spanId = $spanId; $this->traceState = $traceState; $this->isRemote = $isRemote; - $this->isSampled = ($traceFlags & self::SAMPLED_FLAG) === self::SAMPLED_FLAG; + $this->isSampled = ($traceFlags & self::TRACE_FLAG_SAMPLED) === self::TRACE_FLAG_SAMPLED; $this->traceFlags = $traceFlags; - $this->isValid = self::isValidTraceId($this->traceId) && self::isValidSpanId($this->spanId); } public function getTraceId(): string @@ -137,7 +54,7 @@ public function getSpanId(): string return $this->spanId; } - public function getTraceState(): ?API\TraceStateInterface + public function getTraceState(): ?TraceStateInterface { return $this->traceState; } @@ -161,4 +78,38 @@ public function getTraceFlags(): int { return $this->traceFlags; } + + /** @inheritDoc */ + public static function createFromRemoteParent(string $traceId, string $spanId, int $traceFlags = self::TRACE_FLAG_DEFAULT, ?TraceStateInterface $traceState = null): SpanContextInterface + { + return new self( + $traceId, + $spanId, + $traceFlags, + true, + $traceState, + ); + } + + /** @inheritDoc */ + public static function create(string $traceId, string $spanId, int $traceFlags = self::TRACE_FLAG_DEFAULT, ?TraceStateInterface $traceState = null): SpanContextInterface + { + return new self( + $traceId, + $spanId, + $traceFlags, + false, + $traceState, + ); + } + + /** @inheritDoc */ + public static function getInvalid(): SpanContextInterface + { + if (null === self::$invalidContext) { + self::$invalidContext = self::create(SpanContextValidator::INVALID_TRACE, SpanContextValidator::INVALID_SPAN, 0); + } + + return self::$invalidContext; + } } diff --git a/src/API/Trace/SpanContextValidator.php b/src/API/Trace/SpanContextValidator.php new file mode 100644 index 000000000..afe9d4c5b --- /dev/null +++ b/src/API/Trace/SpanContextValidator.php @@ -0,0 +1,35 @@ +with(B3DebugFlagContextKey::instance(), self::IS_SAMPLED); - $isSampled = SpanContext::SAMPLED_FLAG; + $isSampled = SpanContextInterface::TRACE_FLAG_SAMPLED; } else { - $isSampled = ($sampled === SpanContext::SAMPLED_FLAG); + $isSampled = ($sampled === SpanContextInterface::TRACE_FLAG_SAMPLED); } + // Only traceparent header is extracted. No tracestate. return SpanContext::createFromRemoteParent( $traceId, $spanId, diff --git a/src/Extension/Propagator/B3/B3SinglePropagator.php b/src/Extension/Propagator/B3/B3SinglePropagator.php index 78970b807..62a747017 100644 --- a/src/Extension/Propagator/B3/B3SinglePropagator.php +++ b/src/Extension/Propagator/B3/B3SinglePropagator.php @@ -9,6 +9,7 @@ use OpenTelemetry\API\Trace\Span; use OpenTelemetry\API\Trace\SpanContext; use OpenTelemetry\API\Trace\SpanContextInterface; +use OpenTelemetry\API\Trace\SpanContextValidator; use OpenTelemetry\Context\Context; use OpenTelemetry\Context\ContextInterface; use OpenTelemetry\Context\Propagation\ArrayAccessGetterSetter; @@ -156,7 +157,7 @@ private static function extractImpl($carrier, PropagationGetterInterface $getter // Validates the traceId and spanId // Returns an invalid spanContext if any of the checks fail - if (!SpanContext::isValidTraceId($traceId) || !SpanContext::isValidSpanId($spanId)) { + if (!SpanContextValidator::isValidTraceId($traceId) || !SpanContextValidator::isValidSpanId($spanId)) { return SpanContext::getInvalid(); } @@ -165,7 +166,7 @@ private static function extractImpl($carrier, PropagationGetterInterface $getter } $sampled = self::processSampledValue($samplingState); - $isSampled = ($sampled === SpanContext::SAMPLED_FLAG); + $isSampled = ($sampled === SpanContextInterface::TRACE_FLAG_SAMPLED); return SpanContext::createFromRemoteParent( $traceId, diff --git a/src/SDK/Trace/RandomIdGenerator.php b/src/SDK/Trace/RandomIdGenerator.php index 146528e4d..39767fb0f 100644 --- a/src/SDK/Trace/RandomIdGenerator.php +++ b/src/SDK/Trace/RandomIdGenerator.php @@ -4,7 +4,7 @@ namespace OpenTelemetry\SDK\Trace; -use OpenTelemetry\API\Trace\SpanContext; +use OpenTelemetry\API\Trace\SpanContextValidator; use Throwable; class RandomIdGenerator implements IdGeneratorInterface @@ -16,7 +16,7 @@ public function generateTraceId(): string { do { $traceId = $this->randomHex(self::TRACE_ID_HEX_LENGTH); - } while (!SpanContext::isValidTraceId($traceId)); + } while (!SpanContextValidator::isValidTraceId($traceId)); return $traceId; } @@ -25,7 +25,7 @@ public function generateSpanId(): string { do { $spanId = $this->randomHex(self::SPAN_ID_HEX_LENGTH); - } while (!SpanContext::isValidSpanId($spanId)); + } while (!SpanContextValidator::isValidSpanId($spanId)); return $spanId; } diff --git a/tests/Integration/SDK/Context/SpanContextTest.php b/tests/Integration/SDK/Context/SpanContextTest.php index fb8870e62..1685ef68d 100644 --- a/tests/Integration/SDK/Context/SpanContextTest.php +++ b/tests/Integration/SDK/Context/SpanContextTest.php @@ -6,6 +6,7 @@ use OpenTelemetry\API\Trace as API; use OpenTelemetry\API\Trace\SpanContext; +use OpenTelemetry\API\Trace\SpanContextValidator; use OpenTelemetry\API\Trace\TraceState; use OpenTelemetry\SDK\Trace\RandomIdGenerator; use PHPUnit\Framework\TestCase; @@ -21,8 +22,8 @@ class SpanContextTest extends TestCase public function test_invalid_span(string $traceId, string $spanId): void { $spanContext = SpanContext::create($traceId, $spanId); - $this->assertSame(SpanContext::INVALID_TRACE, $spanContext->getTraceId()); - $this->assertSame(SpanContext::INVALID_SPAN, $spanContext->getSpanId()); + $this->assertSame(SpanContextValidator::INVALID_TRACE, $spanContext->getTraceId()); + $this->assertSame(SpanContextValidator::INVALID_SPAN, $spanContext->getSpanId()); } public function invalidSpanData(): array diff --git a/tests/Integration/SDK/SpanBuilderTest.php b/tests/Integration/SDK/SpanBuilderTest.php index 7a52c3c72..0fccedffa 100644 --- a/tests/Integration/SDK/SpanBuilderTest.php +++ b/tests/Integration/SDK/SpanBuilderTest.php @@ -9,6 +9,7 @@ use Mockery\MockInterface; use OpenTelemetry\API\Trace as API; use OpenTelemetry\API\Trace\SpanContext; +use OpenTelemetry\API\Trace\SpanContextValidator; use OpenTelemetry\Context\Context; use OpenTelemetry\Context\ContextInterface; use OpenTelemetry\SDK\Common\Attribute\Attributes; @@ -637,7 +638,7 @@ public function test_set_parent_invalid_context(): void $parentSpan->getContext()->getTraceId() ); - $this->assertFalse(SpanContext::isValidSpanId($span->toSpanData()->getParentSpanId())); + $this->assertFalse(SpanContextValidator::isValidSpanId($span->toSpanData()->getParentSpanId())); $span->end(); $parentSpan->end(); diff --git a/tests/Unit/API/Trace/Propagation/TraceContextPropagatorTest.php b/tests/Unit/API/Trace/Propagation/TraceContextPropagatorTest.php index 907701965..ee8c48850 100644 --- a/tests/Unit/API/Trace/Propagation/TraceContextPropagatorTest.php +++ b/tests/Unit/API/Trace/Propagation/TraceContextPropagatorTest.php @@ -7,6 +7,7 @@ use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator; use OpenTelemetry\API\Trace\SpanContext; use OpenTelemetry\API\Trace\SpanContextInterface; +use OpenTelemetry\API\Trace\SpanContextValidator; use OpenTelemetry\API\Trace\TraceState; use OpenTelemetry\API\Trace\TraceStateInterface; use OpenTelemetry\Context\Context; @@ -60,9 +61,9 @@ public function test_inject_invalid_context(): void null, $this->withSpanContext( SpanContext::create( - SpanContext::INVALID_TRACE, - SpanContext::INVALID_SPAN, - SpanContext::SAMPLED_FLAG + SpanContextValidator::INVALID_TRACE, + SpanContextValidator::INVALID_SPAN, + SpanContextInterface::TRACE_FLAG_SAMPLED ), Context::getCurrent() ) diff --git a/tests/Unit/API/Trace/Propagation/TraceContextValidatorTest.php b/tests/Unit/API/Trace/Propagation/TraceContextValidatorTest.php new file mode 100644 index 000000000..09f39ddfa --- /dev/null +++ b/tests/Unit/API/Trace/Propagation/TraceContextValidatorTest.php @@ -0,0 +1,39 @@ +assertFalse(TraceContextValidator::isValidTraceFlag(self::INVALID_TRACE_FLAG)); + } + + public function test_valid_trace_flag(): void + { + $this->assertTrue(TraceContextValidator::isValidTraceFlag(self::TRACE_FLAG)); + } + + public function test_valid_trace_version(): void + { + $this->assertTrue(TraceContextValidator::isValidTraceVersion(self::TRACE_VERSION)); + } + + public function test_invalid_trace_version(): void + { + $this->assertFalse(TraceContextValidator::isValidTraceVersion(self::INVALID_TRACE_VERSION)); + } +} diff --git a/tests/Unit/API/Trace/SpanContextTest.php b/tests/Unit/API/Trace/SpanContextTest.php index 06ac45181..ebc3741da 100644 --- a/tests/Unit/API/Trace/SpanContextTest.php +++ b/tests/Unit/API/Trace/SpanContextTest.php @@ -6,6 +6,7 @@ use OpenTelemetry\API\Trace as API; use OpenTelemetry\API\Trace\SpanContext; +use OpenTelemetry\API\Trace\SpanContextValidator; use OpenTelemetry\API\Trace\TraceState; use PHPUnit\Framework\TestCase; @@ -37,15 +38,15 @@ public function test_is_valid(): void $this->assertFalse(SpanContext::getInvalid()->isValid()); $this->assertFalse( - SpanContext::create( + SpanContext::createFromRemoteParent( self::FIRST_TRACE_ID, - SpanContext::INVALID_SPAN, + SpanContextValidator::INVALID_SPAN )->isValid() ); $this->assertFalse( - SpanContext::create( - SpanContext::INVALID_TRACE, + SpanContext::createFromRemoteParent( + SpanContextValidator::INVALID_TRACE, self::SECOND_SPAN_ID )->isValid() ); diff --git a/tests/Unit/API/Trace/SpanContextValidatorTest.php b/tests/Unit/API/Trace/SpanContextValidatorTest.php new file mode 100644 index 000000000..583afcbca --- /dev/null +++ b/tests/Unit/API/Trace/SpanContextValidatorTest.php @@ -0,0 +1,37 @@ +assertFalse(SpanContextValidator::isValidTraceID(SpanContextValidator::INVALID_TRACE)); + } + + public function test_valid_trace_id(): void + { + $this->assertTrue(SpanContextValidator::isValidTraceID(self::TRACE_ID)); + } + + public function test_invalid_span_id(): void + { + $this->assertFalse(SpanContextValidator::isValidSpanID(SpanContextValidator::INVALID_SPAN)); + } + + public function test_valid_span_id(): void + { + $this->assertTrue(SpanContextValidator::isValidSpanID(self::SPAN_ID)); + } +} diff --git a/tests/Unit/Extension/Propagator/B3/B3MultiPropagatorTest.php b/tests/Unit/Extension/Propagator/B3/B3MultiPropagatorTest.php index 151c20e5c..4d4ed0b79 100644 --- a/tests/Unit/Extension/Propagator/B3/B3MultiPropagatorTest.php +++ b/tests/Unit/Extension/Propagator/B3/B3MultiPropagatorTest.php @@ -6,6 +6,7 @@ use OpenTelemetry\API\Trace\SpanContext; use OpenTelemetry\API\Trace\SpanContextInterface; +use OpenTelemetry\API\Trace\SpanContextValidator; use OpenTelemetry\Context\Context; use OpenTelemetry\Context\ContextInterface; use OpenTelemetry\Extension\Propagator\B3\B3DebugFlagContextKey; @@ -65,9 +66,9 @@ public function test_inject_invalid_context(): void null, $this->withSpanContext( SpanContext::create( - SpanContext::INVALID_TRACE, - SpanContext::INVALID_SPAN, - SpanContext::SAMPLED_FLAG + SpanContextValidator::INVALID_TRACE, + SpanContextValidator::INVALID_SPAN, + SpanContextInterface::TRACE_FLAG_SAMPLED ), Context::getCurrent() ) diff --git a/tests/Unit/Extension/Propagator/B3/B3SinglePropagatorTest.php b/tests/Unit/Extension/Propagator/B3/B3SinglePropagatorTest.php index 9f58e9471..0d4570b83 100644 --- a/tests/Unit/Extension/Propagator/B3/B3SinglePropagatorTest.php +++ b/tests/Unit/Extension/Propagator/B3/B3SinglePropagatorTest.php @@ -6,6 +6,7 @@ use OpenTelemetry\API\Trace\SpanContext; use OpenTelemetry\API\Trace\SpanContextInterface; +use OpenTelemetry\API\Trace\SpanContextValidator; use OpenTelemetry\Context\Context; use OpenTelemetry\Context\ContextInterface; use OpenTelemetry\Extension\Propagator\B3\B3DebugFlagContextKey; @@ -61,9 +62,9 @@ public function test_inject_invalid_context(): void null, $this->withSpanContext( SpanContext::create( - SpanContext::INVALID_TRACE, - SpanContext::INVALID_SPAN, - SpanContext::SAMPLED_FLAG + SpanContextValidator::INVALID_TRACE, + SpanContextValidator::INVALID_SPAN, + SpanContextInterface::TRACE_FLAG_SAMPLED ), Context::getCurrent() ) diff --git a/tests/Unit/SDK/Trace/RandomIdGeneratorTest.php b/tests/Unit/SDK/Trace/RandomIdGeneratorTest.php index 7376668b2..2ea103f16 100644 --- a/tests/Unit/SDK/Trace/RandomIdGeneratorTest.php +++ b/tests/Unit/SDK/Trace/RandomIdGeneratorTest.php @@ -4,7 +4,7 @@ namespace OpenTelemetry\Tests\Unit\SDK\Trace; -use OpenTelemetry\API\Trace\SpanContext; +use OpenTelemetry\API\Trace\SpanContextValidator; use OpenTelemetry\SDK\Trace\RandomIdGenerator; use PHPUnit\Framework\TestCase; @@ -21,7 +21,7 @@ public function test_generated_trace_id_is_valid(): void $idGenerator = new RandomIdGenerator(); $traceId = $idGenerator->generateTraceId(); - $this->assertEquals(1, preg_match(SpanContext::VALID_TRACE, $traceId)); + $this->assertEquals(1, preg_match(SpanContextValidator::VALID_TRACE, $traceId)); } /** @@ -32,7 +32,7 @@ public function test_generated_span_id_is_valid(): void $idGenerator = new RandomIdGenerator(); $spanId = $idGenerator->generateSpanId(); - $this->assertEquals(1, preg_match(SpanContext::VALID_SPAN, $spanId)); + $this->assertEquals(1, preg_match(SpanContextValidator::VALID_SPAN, $spanId)); } public function test_fallback_algorithm(): void @@ -43,9 +43,9 @@ public function test_fallback_algorithm(): void $method->setAccessible(true); $traceId = $method->invokeArgs($idGenerator, [$reflection->getConstant('TRACE_ID_HEX_LENGTH')]); - $this->assertEquals(1, preg_match(SpanContext::VALID_TRACE, $traceId)); + $this->assertEquals(1, preg_match(SpanContextValidator::VALID_TRACE, $traceId)); $spanId = $method->invokeArgs($idGenerator, [$reflection->getConstant('SPAN_ID_HEX_LENGTH')]); - $this->assertEquals(1, preg_match(SpanContext::VALID_SPAN, $spanId)); + $this->assertEquals(1, preg_match(SpanContextValidator::VALID_SPAN, $spanId)); } } diff --git a/tests/Unit/SDK/Trace/SpanProcessor/SimpleSpanProcessorTest.php b/tests/Unit/SDK/Trace/SpanProcessor/SimpleSpanProcessorTest.php index 1bfe4a6f3..e7568c3fa 100644 --- a/tests/Unit/SDK/Trace/SpanProcessor/SimpleSpanProcessorTest.php +++ b/tests/Unit/SDK/Trace/SpanProcessor/SimpleSpanProcessorTest.php @@ -10,6 +10,7 @@ use Mockery\MockInterface; use OpenTelemetry\API\Trace\SpanContext; use OpenTelemetry\API\Trace\SpanContextInterface; +use OpenTelemetry\API\Trace\SpanContextValidator; use OpenTelemetry\Context\Context; use OpenTelemetry\SDK\Common\Future\CompletedFuture; use OpenTelemetry\SDK\Common\Log\LoggerHolder; @@ -22,7 +23,7 @@ use Psr\Log\LogLevel; /** - * @covers \OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor + * @covers OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor */ class SimpleSpanProcessorTest extends MockeryTestCase { @@ -46,8 +47,8 @@ protected function setUp(): void $this->readableSpan = Mockery::mock(ReadableSpanInterface::class); $this->sampledSpanContext = SpanContext::create( - SpanContext::INVALID_TRACE, - SpanContext::INVALID_SPAN, + SpanContextValidator::INVALID_TRACE, + SpanContextValidator::INVALID_SPAN, SpanContextInterface::TRACE_FLAG_SAMPLED ); diff --git a/tests/Unit/SDK/Trace/SpanTest.php b/tests/Unit/SDK/Trace/SpanTest.php index 4a9dc14ea..c38ef0a82 100644 --- a/tests/Unit/SDK/Trace/SpanTest.php +++ b/tests/Unit/SDK/Trace/SpanTest.php @@ -12,6 +12,7 @@ use OpenTelemetry\API\Trace as API; use OpenTelemetry\API\Trace\NonRecordingSpan; use OpenTelemetry\API\Trace\SpanContext; +use OpenTelemetry\API\Trace\SpanContextValidator; use OpenTelemetry\Context\Context; use OpenTelemetry\SDK\Common\Attribute\Attributes; use OpenTelemetry\SDK\Common\Attribute\AttributesInterface; @@ -312,7 +313,7 @@ public function test_to_span_data_root_span(): void $span->end(); $this->assertFalse($span->getParentContext()->isValid()); - $this->assertFalse(SpanContext::isValidSpanId($span->toSpanData()->getParentSpanId())); + $this->assertFalse(SpanContextValidator::isValidSpanId($span->toSpanData()->getParentSpanId())); } public function test_to_span_data_child_span(): void @@ -752,7 +753,7 @@ private function createTestRootSpan(): Span ->createTestSpan( API\SpanKind::KIND_INTERNAL, null, - SpanContext::INVALID_SPAN + SpanContextValidator::INVALID_SPAN ); }