Skip to content

Loading…

Replace ThriftAdapter with implicit conversions #169

Closed
wants to merge 4 commits into from

2 participants

@franklinhu
  • Cleanup conversion between common and Thrift with .toClassName calls rather than explicit ThriftAdapter(_)
Franklin Hu Fix tests e8e5ac6
@franklinhu franklinhu pushed a commit that closed this pull request
Franklin Hu Replace ThriftAdapter with implicit conversions
Cleanup conversion between common and Thrift classes with implicits
rather than `ThriftAdapter(_)`.

This commit adds these implicits for common.{Annotation, AnnotationType,
BinaryAnnotation, Endpoint, Span}.

Example:
To include the conversions, `import com.twitter.zipkin.conversions.thrift._`
To convert a Span to thrift, call `span.toThrift`.
To convert a Thrift Span to the common Span, call `span.toSpan`.

The `.toThrift` calls are uniform across all classes, whereas thrift to common
conversion depends on the class name.

Author: @franklinhu
Fixes #169
URL: #169
492d56d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 28, 2012
  1. Replace ThriftAdapter with conversion implicits

    Franklin Hu committed
  2. Add newline

    Franklin Hu committed
  3. Add license header, some doc

    Franklin Hu committed
Commits on Sep 30, 2012
  1. Fix tests

    Franklin Hu committed
This page is out of date. Refresh to see the latest.
View
2 project/Project.scala
@@ -28,7 +28,7 @@ object Zipkin extends Build {
Project(
id = "zipkin",
base = file(".")
- ) aggregate(hadoop, hadoopjobrunner, test, thrift, queryService, common, scrooge, collectorScribe, web, cassandra, collectorCore, collectorService)
+ ) aggregate(hadoop, hadoopjobrunner, test, thrift, queryCore, queryService, common, scrooge, collectorScribe, web, cassandra, collectorCore, collectorService)
lazy val hadoop = Project(
View
8 zipkin-cassandra/src/main/scala/com/twitter/zipkin/storage/cassandra/CassandraStorage.scala
@@ -24,7 +24,7 @@ import com.twitter.zipkin.common.Span
import com.twitter.conversions.time._
import scala.collection.JavaConverters._
import com.twitter.zipkin.config.{CassandraConfig, CassandraStorageConfig}
-import com.twitter.zipkin.adapter.ThriftAdapter
+import com.twitter.zipkin.conversions.thrift._
trait CassandraStorage extends Storage with Cassandra {
@@ -57,7 +57,7 @@ trait CassandraStorage extends Storage with Cassandra {
CASSANDRA_STORE_SPAN.incr
WRITE_REQUEST_COUNTER.incr()
val traceKey = span.traceId
- val traceCol = Column[String, gen.Span](createSpanColumnName(span), ThriftAdapter(span)).ttl(cassandraConfig.tracesTimeToLive)
+ val traceCol = Column[String, gen.Span](createSpanColumnName(span), span.toThrift).ttl(cassandraConfig.tracesTimeToLive)
traces.insert(traceKey, traceCol).unit
}
@@ -103,7 +103,7 @@ trait CassandraStorage extends Storage with Cassandra {
traces.multigetRows(ids.toSet.asJava, None, None, Order.Normal, 1).map { rowSet =>
ids.flatMap { id =>
val spans = rowSet.asScala(id).asScala.map {
- case (colName, col) => ThriftAdapter(col.value)
+ case (colName, col) => col.value.toSpan
}
if (spans.isEmpty) {
None
@@ -135,7 +135,7 @@ trait CassandraStorage extends Storage with Cassandra {
traces.multigetRows(ids.toSet.asJava, None, None, Order.Normal, TRACE_MAX_COLS).map { rowSet =>
ids.flatMap { id =>
val spans = rowSet.asScala(id).asScala.map {
- case (colName, col) => ThriftAdapter(col.value)
+ case (colName, col) => col.value.toSpan
}
spans.toSeq match {
View
8 ...in-cassandra/src/test/scala/com/twitter/zipkin/storage/cassandra/CassandraIndexSpec.scala
@@ -23,16 +23,14 @@ import org.specs.mock.{JMocker, ClassMocker}
import com.twitter.conversions.time._
import scala.collection.JavaConverters._
-import com.twitter.zipkin.gen
import com.twitter.cassie.tests.util.FakeCassandra
import com.twitter.ostrich.admin.RuntimeEnvironment
import com.twitter.util.{Eval, Future}
import java.util.{Set => JSet}
import com.twitter.cassie.{BatchMutationBuilder, Column, Order, ColumnFamily}
-import com.twitter.zipkin.config.{CassandraConfig, CassandraIndexConfig}
import com.twitter.io.TempFile
-import com.twitter.zipkin.common.{BinaryAnnotation, Annotation, Span, Endpoint}
-import com.twitter.zipkin.adapter.ThriftAdapter
+import com.twitter.zipkin.config.{CassandraConfig, CassandraIndexConfig}
+import com.twitter.zipkin.common._
class CassandraIndexSpec extends Specification with JMocker with ClassMocker {
object FakeServer extends FakeCassandra
@@ -41,7 +39,7 @@ class CassandraIndexSpec extends Specification with JMocker with ClassMocker {
val ep = Endpoint(123, 123, "service")
def binaryAnnotation(key: String, value: String) =
- BinaryAnnotation(key, ByteBuffer.wrap(value.getBytes), ThriftAdapter(gen.AnnotationType.String), Some(ep))
+ BinaryAnnotation(key, ByteBuffer.wrap(value.getBytes), AnnotationType.String, Some(ep))
val spanId = 456
val ann1 = Annotation(1, "cs", Some(ep))
View
6 ...-cassandra/src/test/scala/com/twitter/zipkin/storage/cassandra/CassandraStorageSpec.scala
@@ -16,7 +16,6 @@
package com.twitter.zipkin.storage.cassandra
import com.twitter.zipkin.config.CassandraStorageConfig
-import com.twitter.zipkin.gen
import com.twitter.cassie.tests.util.FakeCassandra
import com.twitter.conversions.time._
import com.twitter.ostrich.admin.RuntimeEnvironment
@@ -25,8 +24,7 @@ import java.nio.ByteBuffer
import org.specs.mock.{ClassMocker, JMocker}
import org.specs.Specification
import com.twitter.io.TempFile
-import com.twitter.zipkin.adapter.ThriftAdapter
-import com.twitter.zipkin.common.{BinaryAnnotation, Endpoint, Annotation, Span}
+import com.twitter.zipkin.common._
import com.twitter.zipkin.query.Trace
class CassandraStorageSpec extends Specification with JMocker with ClassMocker {
@@ -35,7 +33,7 @@ class CassandraStorageSpec extends Specification with JMocker with ClassMocker {
var cassandraStorage: CassandraStorage = null
def binaryAnnotation(key: String, value: String) =
- BinaryAnnotation(key, ByteBuffer.wrap(value.getBytes), ThriftAdapter(gen.AnnotationType.String), Some(ep))
+ BinaryAnnotation(key, ByteBuffer.wrap(value.getBytes), AnnotationType.String, Some(ep))
val ep = Endpoint(123, 123, "service")
View
4 zipkin-cassandra/src/test/scala/com/twitter/zipkin/storage/cassandra/SnappyCodecSpec.scala
@@ -18,8 +18,8 @@ package com.twitter.zipkin.storage.cassandra
import org.specs.Specification
import com.twitter.zipkin.gen
import com.twitter.zipkin.common.{Span, Endpoint, Annotation}
+import com.twitter.zipkin.conversions.thrift._
import collection.mutable.ArrayBuffer
-import com.twitter.zipkin.adapter.ThriftAdapter
class SnappyCodecSpec extends Specification {
@@ -34,7 +34,7 @@ class SnappyCodecSpec extends Specification {
new Annotation(2, gen.Constants.CLIENT_SEND, Some(Endpoint(23567, 345, "service"))),
new Annotation(3, gen.Constants.CLIENT_RECV, Some(Endpoint(23567, 345, "service")))),
ArrayBuffer())
- val actual = ThriftAdapter(snappyCodec.decode(snappyCodec.encode(ThriftAdapter(expected))))
+ val actual = snappyCodec.decode(snappyCodec.encode(expected.toThrift)).toSpan
expected mustEqual actual
}
View
4 ...collector-scribe/src/main/scala/com/twitter/zipkin/collector/processor/ScribeFilter.scala
@@ -21,7 +21,7 @@ import com.twitter.logging.Logger
import com.twitter.ostrich.stats.Stats
import com.twitter.scrooge.BinaryThriftStructSerializer
import com.twitter.util.Future
-import com.twitter.zipkin.adapter.ThriftAdapter
+import com.twitter.zipkin.conversions.thrift._
import com.twitter.zipkin.common.Span
import com.twitter.zipkin.gen
@@ -47,7 +47,7 @@ class ScribeFilter extends Filter[Seq[String], Unit, Span, Unit] {
deserializer.fromString(msg)
}
log.ifDebug("Processing span: " + span + " from " + msg)
- service(ThriftAdapter(span))
+ service(span.toSpan)
} catch {
case e: Exception => {
// scribe doesn't have any ResultCode.ERROR or similar
View
6 ...ector-scribe/src/test/scala/com/twitter/zipkin/collector/ScribeCollectorServiceSpec.scala
@@ -21,8 +21,8 @@ import com.twitter.util.Future
import com.twitter.zipkin.common.{Span, Annotation}
import com.twitter.zipkin.config.sampler.AdjustableRateConfig
import com.twitter.zipkin.config.ScribeZipkinCollectorConfig
+import com.twitter.zipkin.conversions.thrift._
import com.twitter.zipkin.gen
-import com.twitter.zipkin.adapter.ThriftAdapter
import com.twitter.zipkin.storage.Aggregates
import org.specs.Specification
import org.specs.mock.{ClassMocker, JMocker}
@@ -34,9 +34,9 @@ class ScribeCollectorServiceSpec extends Specification with JMocker with ClassMo
val category = "zipkin"
val validSpan = Span(123, "boo", 456, None, List(new Annotation(1, "bah", None)), Nil)
- val validList = List(gen.LogEntry(category, serializer.toString(ThriftAdapter(validSpan))))
+ val validList = List(gen.LogEntry(category, serializer.toString(validSpan.toThrift)))
- val wrongCatList = List(gen.LogEntry("wrongcat", serializer.toString(ThriftAdapter(validSpan))))
+ val wrongCatList = List(gen.LogEntry("wrongcat", serializer.toString(validSpan.toThrift)))
val base64 = "CgABAAAAAAAAAHsLAAMAAAADYm9vCgAEAAAAAAAAAcgPAAYMAAAAAQoAAQAAAAAAAAABCwACAAAAA2JhaAAPAAgMAAAAAAIACQAA"
View
4 ...ector-scribe/src/test/scala/com/twitter/zipkin/collector/processor/ScribeFilterSpec.scala
@@ -17,8 +17,8 @@ package com.twitter.zipkin.collector.processor
import com.twitter.finagle.Service
import com.twitter.scrooge.BinaryThriftStructSerializer
-import com.twitter.zipkin.adapter.ThriftAdapter
import com.twitter.zipkin.common.{Annotation, Span}
+import com.twitter.zipkin.conversions.thrift._
import com.twitter.zipkin.gen
import org.specs.Specification
import org.specs.mock.{JMocker, ClassMocker}
@@ -37,7 +37,7 @@ class ScribeFilterSpec extends Specification with JMocker with ClassMocker {
val endline = Seq("CgABAAAAAAAAAHsLAAMAAAADYm9vCgAEAAAAAAAAAcgPAAYMAAAAAQoAAQAAAAAAAAABCwACAAAAA2JhaAAPAAgMAAAAAAA=\n")
val validSpan = Span(123, "boo", 456, None, List(new Annotation(1, "bah", None)), Nil)
- val serialized = Seq(serializer.toString(ThriftAdapter(validSpan)))
+ val serialized = Seq(serializer.toString(validSpan.toThrift))
val bad = Seq("garbage!")
val filter = new ScribeFilter
View
23 zipkin-query-core/src/test/scala/com/twitter/zipkin/query/QueryServiceSpec.scala
@@ -17,8 +17,9 @@
package com.twitter.zipkin.query
import com.twitter.util.Future
-import com.twitter.zipkin.adapter.{ThriftQueryAdapter, ThriftAdapter}
+import com.twitter.zipkin.adapter.{ThriftQueryAdapter}
import com.twitter.zipkin.common._
+import com.twitter.zipkin.conversions.thrift._
import com.twitter.zipkin.gen
import com.twitter.zipkin.query.adjusters.{TimeSkewAdjuster, NullAdjuster}
import com.twitter.zipkin.storage._
@@ -256,13 +257,13 @@ class QueryServiceSpec extends Specification with JMocker with ClassMocker {
}
val ann1 = gen.TimelineAnnotation(100, gen.Constants.CLIENT_SEND,
- ThriftAdapter(ep1), 666, None, "service1", "methodcall")
+ ep1.toThrift, 666, None, "service1", "methodcall")
val ann2 = gen.TimelineAnnotation(150, gen.Constants.CLIENT_RECV,
- ThriftAdapter(ep1), 666, None, "service1", "methodcall")
+ ep1.toThrift, 666, None, "service1", "methodcall")
val ann3 = gen.TimelineAnnotation(110, gen.Constants.SERVER_RECV,
- ThriftAdapter(ep2), 666, None, "service2", "methodcall")
+ ep2.toThrift, 666, None, "service2", "methodcall")
val ann4 = gen.TimelineAnnotation(140, gen.Constants.SERVER_SEND,
- ThriftAdapter(ep2), 666, None, "service2", "methodcall")
+ ep2.toThrift, 666, None, "service2", "methodcall")
val expected = List(gen.TraceTimeline(1L, 666, List(ann1, ann3, ann4, ann2), List()))
val actual = qs.getTraceTimelinesByIds(List(1L), List(gen.Adjust.Nothing, gen.Adjust.TimeSkew))()
@@ -278,11 +279,11 @@ class QueryServiceSpec extends Specification with JMocker with ClassMocker {
// these are real traces, except for timestap that has been chopped down to make easier to spot
// differences
val epKoalabird = Some(Endpoint(170024040, -26945, "koalabird-cuckoo"))
- val epKoalabirdT = ThriftAdapter(epKoalabird.get)
+ val epKoalabirdT = epKoalabird.get.toThrift
val epCuckoo = Some(Endpoint(170061954, 9149, "cuckoo.thrift"))
- val epCuckooT = ThriftAdapter(epCuckoo.get)
+ val epCuckooT = epCuckoo.get.toThrift
val epCuckooCassie = Some(Endpoint(170061954, -24936, "client"))
- val epCuckooCassieT = ThriftAdapter(epCuckooCassie.get)
+ val epCuckooCassieT = epCuckooCassie.get.toThrift
val rs1 = Span(4488677265848750007L, "ValuesFromSource", 4488677265848750007L, None, List(
Annotation(6712580L, "cs", epKoalabird),
@@ -341,11 +342,11 @@ class QueryServiceSpec extends Specification with JMocker with ClassMocker {
// these are real traces, except for timestap that has been chopped down to make easier to spot
// differences
val epKoalabird = Some(Endpoint(170021254, -24672, "koalabird-cuckoo"))
- val epKoalabirdT = ThriftAdapter(epKoalabird.get)
+ val epKoalabirdT = epKoalabird.get.toThrift
val epCuckoo = Some(Endpoint(170062191, 9149, "cuckoo.thrift"))
- val epCuckooT = ThriftAdapter(epCuckoo.get)
+ val epCuckooT = epCuckoo.get.toThrift
val epCuckooCassie = Some(Endpoint(170062191, -8985, "client"))
- val epCuckooCassieT = ThriftAdapter(epCuckooCassie.get)
+ val epCuckooCassieT = epCuckooCassie.get.toThrift
val rs1 = Span(-6120267009876080004L, "ValuesFromSource", -6120267009876080004L, None, List(
Annotation(630715L, "cs", epKoalabird),
View
3 ...in-query-core/src/test/scala/com/twitter/zipkin/query/conversions/TraceTimelineSpec.scala
@@ -15,7 +15,6 @@
*/
package com.twitter.zipkin.query.conversions
-import com.twitter.zipkin.adapter.ThriftAdapter
import com.twitter.zipkin.common._
import com.twitter.zipkin.gen
import com.twitter.zipkin.query.{Trace, TimelineAnnotation, TraceTimeline}
@@ -72,7 +71,7 @@ class TraceTimelineSpec extends Specification with JMocker with ClassMocker {
val ann5 = Annotation(85, gen.Constants.CLIENT_RECV, endpoint2)
val ann6 = Annotation(87, gen.Constants.CLIENT_RECV, endpoint3)
- val ba1 = BinaryAnnotation("key1", ByteBuffer.wrap("value1".getBytes), ThriftAdapter(gen.AnnotationType.String), None)
+ val ba1 = BinaryAnnotation("key1", ByteBuffer.wrap("value1".getBytes), AnnotationType.String, None)
val span1 = Span(1, "ValuesFromSource", 2209720933601260005L, None,
List(ann3, ann6), List(ba1))
View
118 zipkin-scrooge/src/main/scala/com/twitter/zipkin/adapter/ThriftAdapter.scala
@@ -1,118 +0,0 @@
-/*
- * Copyright 2012 Twitter Inc.
- *
- * Licensed 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 com.twitter.zipkin.adapter
-
-import com.twitter.util.Duration
-import com.twitter.zipkin.gen
-import com.twitter.zipkin.common._
-import java.util.concurrent.TimeUnit
-
-object ThriftAdapter extends Adapter {
- type annotationType = gen.Annotation
- type annotationTypeType = gen.AnnotationType
- type binaryAnnotationType = gen.BinaryAnnotation
- type endpointType = gen.Endpoint
- type spanType = gen.Span
-
- /* Annotation from Thrift */
- def apply(a: annotationType): Annotation = {
- if (a.timestamp <= 0)
- throw new IllegalArgumentException("Annotation must have a timestamp: %s".format(a.toString))
-
- if ("".equals(a.value))
- throw new IllegalArgumentException("Annotation must have a value: %s".format(a.toString))
-
- new Annotation(a.timestamp, a.value, a.host.map { this(_) }, a.duration.map(Duration(_, TimeUnit.MICROSECONDS)))
- }
-
- /* Annotation to Thrift */
- def apply(a: Annotation): annotationType = {
- gen.Annotation(a.timestamp, a.value, a.host.map { this(_) }, a.duration.map(_.inMicroseconds.toInt))
- }
-
- /* AnnotationType from Thrift */
- def apply(a: annotationTypeType): AnnotationType = {
- AnnotationType(a.value, a.name)
- }
-
- /* AnnotationType to Thrift */
- def apply(a: AnnotationType): annotationTypeType = {
- gen.AnnotationType(a.value)
- }
-
- /* BinaryAnnotation from Thrift */
- def apply(b: binaryAnnotationType): BinaryAnnotation = {
- BinaryAnnotation(
- b.`key`,
- b.`value`,
- this(b.`annotationType`),
- b.`host`.map { this(_) }
- )
- }
-
- /* BinaryAnnotation to Thrift */
- def apply(b: BinaryAnnotation): binaryAnnotationType = {
- gen.BinaryAnnotation(
- b.key,
- b.value,
- this(b.annotationType),
- b.host.map { this(_) }
- )
- }
-
- /* Endpoint from Thrift */
- def apply(e: endpointType): Endpoint = {
- val serviceName = e.serviceName match {
- case null => Endpoint.UnknownServiceName
- case "" => Endpoint.UnknownServiceName
- case _ => e.serviceName
- }
-
- new Endpoint(e.ipv4, e.port, serviceName)
- }
-
- /* Endpoint to Thrift */
- def apply(e: Endpoint): endpointType = {
- gen.Endpoint(e.ipv4, e.port, e.serviceName)
- }
-
- /* Span from Thrift */
- def apply(s: spanType): Span = {
- s.`name` match {
- case null => throw new IncompleteTraceDataException("No name set in Span")
- case _ => ()
- }
-
- val annotations = s.annotations match {
- case null => List[Annotation]()
- case as => as.map { this(_) }.toList
- }
-
- val binaryAnnotations = s.binaryAnnotations match {
- case null => Seq[BinaryAnnotation]()
- case b => b.map { this(_) }
- }
-
- new Span(s.traceId, s.name, s.id, s.parentId, annotations, binaryAnnotations, s.debug)
- }
-
- /* Span to Thrift */
- def apply(s: Span): spanType = {
- gen.Span(s.traceId, s.name, s.id, s.parentId, s.annotations.map { this(_) },
- s.binaryAnnotations.map { this(_) }, s.debug)
- }
-}
View
21 zipkin-scrooge/src/main/scala/com/twitter/zipkin/adapter/ThriftQueryAdapter.scala
@@ -15,6 +15,7 @@
*/
package com.twitter.zipkin.adapter
+import com.twitter.zipkin.conversions.thrift._
import com.twitter.zipkin.gen
import com.twitter.zipkin.query._
@@ -35,7 +36,7 @@ object ThriftQueryAdapter extends QueryAdapter {
TimelineAnnotation(
t.`timestamp`,
t.`value`,
- ThriftAdapter(t.`host`),
+ t.`host`.toEndpoint,
t.`spanId`,
t.`parentId`,
t.`serviceName`,
@@ -47,7 +48,7 @@ object ThriftQueryAdapter extends QueryAdapter {
gen.TimelineAnnotation(
t.timestamp,
t.value,
- ThriftAdapter(t.host),
+ t.host.toThrift,
t.spanId,
t.parentId,
t.serviceName,
@@ -60,7 +61,7 @@ object ThriftQueryAdapter extends QueryAdapter {
t.`traceId`,
t.`rootMostSpanId`,
t.`annotations`.map { ThriftQueryAdapter(_) },
- t.`binaryAnnotations`.map { ThriftAdapter(_) })
+ t.`binaryAnnotations`.map { _.toBinaryAnnotation })
}
/* TraceTimeline to Thrift */
@@ -69,7 +70,7 @@ object ThriftQueryAdapter extends QueryAdapter {
t.traceId,
t.rootSpanId,
t.annotations.map { ThriftQueryAdapter(_) },
- t.binaryAnnotations.map { ThriftAdapter(_) })
+ t.binaryAnnotations.map { _.toThrift })
}
/* TraceCombo from Thrift */
@@ -94,23 +95,23 @@ object ThriftQueryAdapter extends QueryAdapter {
def apply(t: traceSummaryType): TraceSummary = {
new TraceSummary(t.traceId, t.startTimestamp, t.endTimestamp,
t.durationMicro, t.serviceCounts,
- t.endpoints.map(ThriftAdapter(_)).toList)
+ t.endpoints.map { _.toEndpoint }.toList)
}
/* TraceSummary to Thrift */
def apply(t: TraceSummary): traceSummaryType = {
gen.TraceSummary(t.traceId, t.startTimestamp, t.endTimestamp,
- t.durationMicro, t.serviceCounts, t.endpoints.map(ThriftAdapter(_)))
+ t.durationMicro, t.serviceCounts, t.endpoints.map { _.toThrift })
}
/* Trace from Thrift */
def apply(t: traceType): Trace = {
- Trace(t.`spans`.map(ThriftAdapter(_)))
+ Trace(t.spans.map { _.toSpan })
}
/* Trace to Thrift */
def apply(t: Trace): traceType = {
- gen.Trace(t.spans.map(ThriftAdapter(_)))
+ gen.Trace(t.spans.map{ _.toThrift })
}
/* QueryRequest */
@@ -120,7 +121,7 @@ object ThriftQueryAdapter extends QueryAdapter {
q.`spanName`,
q.`annotations`,
q.`binaryAnnotations`.map {
- _.map { ThriftAdapter(_) }
+ _.map { _.toBinaryAnnotation }
},
q.`endTs`,
q.`limit`,
@@ -132,7 +133,7 @@ object ThriftQueryAdapter extends QueryAdapter {
q.spanName,
q.annotations,
q.binaryAnnotations.map {
- _.map { ThriftAdapter(_) }
+ _.map { _.toThrift }
},
q.endTs,
q.limit,
View
117 zipkin-scrooge/src/main/scala/com/twitter/zipkin/conversions/thrift.scala
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2012 Twitter Inc.
+ *
+ * Licensed 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 com.twitter.zipkin.conversions
+
+import com.twitter.conversions.time._
+import com.twitter.zipkin.common._
+import com.twitter.zipkin.gen
+import com.twitter.zipkin.common.BinaryAnnotation
+import com.twitter.zipkin.common.Annotation
+
+/**
+ * Convenience implicits for converting between common classes and Thrift.
+ */
+object thrift {
+ /* Endpoint */
+ class ThriftEndpoint(e: Endpoint) {
+ def toThrift = gen.Endpoint(e.ipv4, e.port, e.serviceName)
+ }
+ class WrappedEndpoint(e: gen.Endpoint) {
+ def toEndpoint = {
+ val serviceName = e.serviceName match {
+ case (null | "") => Endpoint.UnknownServiceName
+ case _ => e.serviceName
+ }
+ new Endpoint(e.ipv4, e.port, serviceName)
+ }
+ }
+ implicit def endpointToThriftEndpoint(e: Endpoint) = new ThriftEndpoint(e)
+ implicit def thriftEndpointToEndpoint(e: gen.Endpoint) = new WrappedEndpoint(e)
+
+ /* AnnotationType */
+ class ThriftAnnotationType(a: AnnotationType) {
+ def toThrift = gen.AnnotationType(a.value)
+ }
+ class WrappedAnnotationType(a: gen.AnnotationType) {
+ def toAnnotationType = AnnotationType(a.value, a.name)
+ }
+ implicit def annotationTypeToThriftAnnotationType(a: AnnotationType) = new ThriftAnnotationType(a)
+ implicit def thriftAnnotationTypeToAnnotationType(a: gen.AnnotationType) = new WrappedAnnotationType(a)
+
+ /* Annotation */
+ class ThriftAnnotation(a: Annotation) {
+ def toThrift = {
+ gen.Annotation(a.timestamp, a.value, a.host.map { _.toThrift }, a.duration.map(_.inMicroseconds.toInt))
+ }
+ }
+ class WrappedAnnotation(a: gen.Annotation) {
+ def toAnnotation = {
+ if (a.timestamp <= 0)
+ throw new IllegalArgumentException("Annotation must have a timestamp: %s".format(a.toString))
+
+ if ("".equals(a.value))
+ throw new IllegalArgumentException("Annotation must have a value: %s".format(a.toString))
+
+ new Annotation(a.timestamp, a.value, a.host.map { _.toEndpoint }, a.duration.map { _.microseconds })
+ }
+ }
+ implicit def annotationToThriftAnnotation(a: Annotation) = new ThriftAnnotation(a)
+ implicit def thriftAnnotationToAnnotation(a: gen.Annotation) = new WrappedAnnotation(a)
+
+ /* BinaryAnnotation */
+ class ThriftBinaryAnnotation(b: BinaryAnnotation) {
+ def toThrift = {
+ gen.BinaryAnnotation(b.key, b.value, b.annotationType.toThrift, b.host.map { _.toThrift })
+ }
+ }
+ class WrappedBinaryAnnotation(b: gen.BinaryAnnotation) {
+ def toBinaryAnnotation = {
+ BinaryAnnotation(b.key, b.value, b.annotationType.toAnnotationType, b.host.map { _.toEndpoint })
+ }
+ }
+ implicit def binaryAnnotationToThriftBinaryAnnotation(b: BinaryAnnotation) = new ThriftBinaryAnnotation(b)
+ implicit def thriftBinaryAnnotationToBinaryAnnotation(b: gen.BinaryAnnotation) = new WrappedBinaryAnnotation(b)
+
+ /* Span */
+ class ThriftSpan(s: Span) {
+ def toThrift = {
+ gen.Span(s.traceId, s.name, s.id, s.parentId, s.annotations.map { _.toThrift },
+ s.binaryAnnotations.map { _.toThrift }, s.debug)
+ }
+ }
+ class WrappedSpan(s: gen.Span) {
+ def toSpan = {
+ s.name match {
+ case null => throw new IncompleteTraceDataException("No name set in Span")
+ case _ => ()
+ }
+
+ val annotations = s.annotations match {
+ case null => List.empty[Annotation]
+ case as => as.map { _.toAnnotation }.toList
+ }
+
+ val binaryAnnotations = s.binaryAnnotations match {
+ case null => List.empty[BinaryAnnotation]
+ case b => b.map { _.toBinaryAnnotation }
+ }
+
+ new Span(s.traceId, s.name, s.id, s.parentId, annotations, binaryAnnotations, s.debug)
+ }
+ }
+ implicit def spanToThriftSpan(s: Span) = new ThriftSpan(s)
+ implicit def thriftSpanToSpan(s: gen.Span) = new WrappedSpan(s)
+}
View
42 ...er/zipkin/adapter/ThriftAdapterSpec.scala → ...ipkin/adapter/ThriftConversionsSpec.scala
@@ -16,29 +16,25 @@
*/
package com.twitter.zipkin.adapter
+import com.twitter.conversions.time._
import com.twitter.zipkin.common._
+import com.twitter.zipkin.conversions.thrift._
import com.twitter.zipkin.gen
-import com.twitter.conversions.time._
-
import org.specs.Specification
import org.specs.mock.{ClassMocker, JMocker}
import java.nio.ByteBuffer
-class ThriftAdapterSpec extends Specification with JMocker with ClassMocker {
+class ThriftConversionsSpec extends Specification with JMocker with ClassMocker {
- "ThriftAdapter" should {
+ "ThriftConversions" should {
"convert Annotation" in {
"to thrift and back" in {
val expectedAnn: Annotation = Annotation(123, "value", Some(Endpoint(123, 123, "service")))
- val thriftAnn: gen.Annotation = ThriftAdapter(expectedAnn)
- val actualAnn: Annotation = ThriftAdapter(thriftAnn)
- expectedAnn mustEqual actualAnn
+ expectedAnn.toThrift.toAnnotation mustEqual expectedAnn
}
"to thrift and back, with duration" in {
val expectedAnn: Annotation = Annotation(123, "value", Some(Endpoint(123, 123, "service")), Some(1.seconds))
- val thriftAnn: gen.Annotation = ThriftAdapter(expectedAnn)
- val actualAnn: Annotation = ThriftAdapter(thriftAnn)
- expectedAnn mustEqual actualAnn
+ expectedAnn.toThrift.toAnnotation mustEqual expectedAnn
}
}
@@ -47,9 +43,7 @@ class ThriftAdapterSpec extends Specification with JMocker with ClassMocker {
"to thrift and back" in {
types.zipWithIndex.foreach { case (value: String, index: Int) =>
val expectedAnnType: AnnotationType = AnnotationType(index, value)
- val thriftAnnType: gen.AnnotationType = ThriftAdapter(expectedAnnType)
- val actualAnnType: AnnotationType = ThriftAdapter(thriftAnnType)
- actualAnnType mustEqual expectedAnnType
+ expectedAnnType.toThrift.toAnnotationType mustEqual expectedAnnType
}
}
}
@@ -60,25 +54,21 @@ class ThriftAdapterSpec extends Specification with JMocker with ClassMocker {
val expectedHost = Some(Endpoint(123, 456, "service"))
val expectedBA: BinaryAnnotation =
BinaryAnnotation("something", ByteBuffer.wrap("else".getBytes), expectedAnnType, expectedHost)
- val thriftBA: gen.BinaryAnnotation = ThriftAdapter(expectedBA)
- val actualBA: BinaryAnnotation = ThriftAdapter(thriftBA)
- actualBA mustEqual expectedBA
+ expectedBA.toThrift.toBinaryAnnotation mustEqual expectedBA
}
}
"convert Endpoint" in {
"to thrift and back" in {
val expectedEndpoint: Endpoint = Endpoint(123, 456, "service")
- val thriftEndpoint: gen.Endpoint = ThriftAdapter(expectedEndpoint)
- val actualEndpoint: Endpoint = ThriftAdapter(thriftEndpoint)
- expectedEndpoint mustEqual actualEndpoint
+ expectedEndpoint.toThrift.toEndpoint mustEqual expectedEndpoint
}
"to thrift and back, with null service" in {
// TODO this could happen if we deserialize an old style struct
- val actualEndpoint = ThriftAdapter(gen.Endpoint(123, 456, null))
+ val actualEndpoint = gen.Endpoint(123, 456, null)
val expectedEndpoint = Endpoint(123, 456, Endpoint.UnknownServiceName)
- expectedEndpoint mustEqual actualEndpoint
+ actualEndpoint.toEndpoint mustEqual expectedEndpoint
}
}
@@ -89,20 +79,18 @@ class ThriftAdapterSpec extends Specification with JMocker with ClassMocker {
List(expectedAnnotation), Nil)
"to thrift and back" in {
- val thriftSpan: gen.Span = ThriftAdapter(expectedSpan)
- val actualSpan: Span = ThriftAdapter(thriftSpan)
- expectedSpan mustEqual actualSpan
+ expectedSpan.toThrift.toSpan mustEqual expectedSpan
}
"handle incomplete thrift span" in {
val noNameSpan = gen.Span(0, null, 0, None, Seq(), Seq())
- ThriftAdapter(noNameSpan) must throwA[IncompleteTraceDataException]
+ noNameSpan.toSpan must throwA[IncompleteTraceDataException]
val noAnnotationsSpan = gen.Span(0, "name", 0, None, null, Seq())
- ThriftAdapter(noAnnotationsSpan) mustEqual Span(0, "name", 0, None, List(), Seq())
+ noAnnotationsSpan.toSpan mustEqual Span(0, "name", 0, None, List(), Seq())
val noBinaryAnnotationsSpan = gen.Span(0, "name", 0, None, Seq(), null)
- ThriftAdapter(noBinaryAnnotationsSpan) mustEqual Span(0, "name", 0, None, List(), Seq())
+ noBinaryAnnotationsSpan.toSpan mustEqual Span(0, "name", 0, None, List(), Seq())
}
}
}
View
6 zipkin-test/src/main/scala/com/twitter/zipkin/tracegen/TraceGen.scala
@@ -22,7 +22,7 @@ import java.nio.ByteBuffer
import collection.mutable.ListBuffer
import scala.util.Random
import com.twitter.zipkin.common._
-import com.twitter.zipkin.adapter.ThriftAdapter
+import com.twitter.zipkin.conversions.thrift._
/**
* Here be dragons. Not terribly nice dragons.
@@ -112,12 +112,12 @@ class TraceGen {
val clientAnnotations = List(cs, cr)
val spanClient = Span(traceId, spanName, spanId, parentSpanId, clientAnnotations,
- Seq(ThriftAdapter(gen.BinaryAnnotation("key", ByteBuffer.wrap("value".getBytes), gen.AnnotationType.String, None))))
+ Seq(gen.BinaryAnnotation("key", ByteBuffer.wrap("value".getBytes), gen.AnnotationType.String, None).toBinaryAnnotation))
val serverAnnotations = List(sr, ss) ::: customAnnotations
val spanServer = Span(traceId, spanName, spanId, parentSpanId, serverAnnotations, Nil)
- (ThriftAdapter(spanClient), ThriftAdapter(spanServer), rvStartTimestamp, timestamp)
+ (spanClient.toThrift, spanServer.toThrift, rvStartTimestamp, timestamp)
}
}
Something went wrong with that request. Please try again.