Skip to content

Commit

Permalink
tolerate up to 128-bit span ids by dropping higher bits (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
levkhomich committed Oct 23, 2016
1 parent 03c5cb7 commit b740fe1
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,25 @@ object SpanMetadata {
}

private[tracing] def idFromString(x: String): Long = {
if (x == null || x.length == 0 || x.length > 16)
throw new NumberFormatException("Invalid span id string: " + x)
val s =
if (x.length % 2 == 0) x
else "0" + x
val bytes = new Array[Byte](8)
val start = 7 - (s.length + 1) / 2
(s.length until 0 by -2).foreach {
i =>
val x = Integer.parseInt(s.substring(i - 2, i), 16).toByte
bytes.update(start + i / 2, x)
if (x == null || x.length == 0) {
throw new NumberFormatException("Empty span id")
} else if (x.length > 32) {
throw new NumberFormatException("Span id is too long: " + x)
} else if (x.length > 16) {
idFromString(x.takeRight(16))
} else {
val s =
if (x.length % 2 == 0) x
else "0" + x
val bytes = new Array[Byte](8)
val start = 7 - (s.length + 1) / 2
(s.length until 0 by -2).foreach {
i =>
val x = Integer.parseInt(s.substring(i - 2, i), 16).toByte
bytes.update(start + i / 2, x)
}
new DataInputStream(new ByteArrayInputStream(bytes)).readLong
}
new DataInputStream(new ByteArrayInputStream(bytes)).readLong
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package com.github.levkhomich.akka.tracing

import scala.util.Random

import com.github.kristofa.brave.SpanId
import com.github.kristofa.brave.{ IdConversion, SpanId }
import org.specs2.mutable.Specification

class SpanMetadataSpec extends Specification with TracingTestCommons {
Expand Down Expand Up @@ -54,7 +54,7 @@ class SpanMetadataSpec extends Specification with TracingTestCommons {
failure(s"SpanId deserialization failed for value $x (was $actual instead of $expected)")
}

checkValue("FFFFFFFFFFFFFFFF")
checkValue("ffffffffffffffff")
checkValue("0")
checkValue("00")
checkValue("0000000000000000")
Expand All @@ -75,8 +75,37 @@ class SpanMetadataSpec extends Specification with TracingTestCommons {
SpanMetadata.idFromString(null) must throwAn[NumberFormatException]
SpanMetadata.idFromString("") must throwAn[NumberFormatException]
SpanMetadata.idFromString("not a number") must throwAn[NumberFormatException]
SpanMetadata.idFromString("11111111111111111") must throwAn[NumberFormatException]
SpanMetadata.idFromString("11111111111111111") must throwAn[NumberFormatException]
}

"tolerate up to 128-bit span ids by dropping higher bits" in {
def checkValue(x: String): Unit = {
val actual = SpanMetadata.idFromString(x)
val expected = IdConversion.convertToLong(x)
if (actual != expected)
failure(s"SpanId deserialization failed for value $x (was $actual instead of $expected)")
}

checkValue("463ac35c9f6413ad48485a3953bb612412") should throwA[NumberFormatException]

checkValue("463ac35c9f6413ad48485a3953bb6124")
checkValue("463ac35c9f6413ad48485a3953")
checkValue("463ac35c9f6413ad48485")
checkValue("463ac35c9f6413ad")
checkValue("ffffffffffffffffffffffffffffffff")
checkValue("0")
checkValue("00")
checkValue("00000000000000000000000000000000")
checkValue("1")
checkValue("11")
checkValue("111")

for (_ <- 1L to IterationsCount)
checkValue {
val str = Random.nextLong().toString.replace("-", "")
str.substring(0, (Random.nextInt(15) + 1) min str.length)
}

success
}

"provide metadata [de]serialization support" in {
Expand Down

0 comments on commit b740fe1

Please sign in to comment.