Skip to content

Commit

Permalink
Merge pull request #21 from ExpediaDotCom/zipkin-blobs
Browse files Browse the repository at this point in the history
Adding a module for Zipkin-Blobs
  • Loading branch information
keshavpeswani authored Nov 19, 2019
2 parents 4efbe9d + df46e8a commit 734fc22
Show file tree
Hide file tree
Showing 8 changed files with 308 additions and 16 deletions.
6 changes: 3 additions & 3 deletions haystack-blobs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-api</artifactId>
<version>${opentracing.version}</version>
<groupId>com.expedia.www</groupId>
<artifactId>haystack-client-core</artifactId>
<version>0.2.8</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.expedia.blobs.core.BlobContext;
import com.expedia.blobs.core.BlobType;
import com.expedia.blobs.core.BlobWriter;
import io.opentracing.Span;
import com.expedia.www.haystack.client.Span;
import org.apache.commons.lang3.Validate;

/**
Expand All @@ -14,33 +14,30 @@
public class SpanBlobContext implements BlobContext {

private final Span span;
private final String serviceName;
private final static String PARTIAL_BLOB_KEY = "-blob";
private final String operationName;

/**
* constructor
* @param span span object
* @param serviceName for a specific service name, can't be null or empty
* @param operationName for a specific operation name
*/
public SpanBlobContext(Span span, String serviceName, String operationName) {
public SpanBlobContext(Span span) {
Validate.notNull(span, "span cannot be null in context");
Validate.notEmpty(serviceName, "service name cannot be null in context");

this.span = span;
this.serviceName = serviceName;
this.operationName = operationName;
}

@Override
public String getOperationName() {
return operationName;
return this.span.getOperationName();
}

@Override
public String getServiceName() {
return serviceName;
return this.span.getServiceName();
}

@Override
public String getOperationId() {
return this.span.context().getSpanId().toString();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package com.expedia.haystack.blobs

import java.util

import com.expedia.blobs.core.BlobType
import com.expedia.www.haystack.client._
import org.easymock.EasyMock
import org.scalatest.easymock.EasyMockSugar
import org.scalatest.{FunSpec, Matchers}

Expand All @@ -9,10 +14,31 @@ class SpanBlobContextSpec extends FunSpec with Matchers with EasyMockSugar {

it("should throw an error if span is not present") {
val catchExpection = intercept[Exception] {
val _ = new SpanBlobContext(null, "", "")
val _ = new SpanBlobContext(null)
}

catchExpection.getMessage shouldEqual "span cannot be null in context"
}

it("should add a tag to the Span when onBlobKeyCreate is invoked") {
val spanContext = mock[SpanContext]
val tracer = mock[Tracer]
val tags = new util.HashMap[String, Object]
val span = MockSpanBuilder.mockSpan(tracer, mock[Clock], "span-name", spanContext,
System.currentTimeMillis(), tags, new util.ArrayList[Reference])
val spanBlobContext = new SpanBlobContext(span)

expecting {
tracer.getServiceName.andReturn("remote-service").once()
spanContext.getSpanId.andReturn("1234567890").once()
}
EasyMock.replay(tracer, spanContext)


spanBlobContext.onBlobKeyCreate(spanBlobContext.makeKey(BlobType.REQUEST), BlobType.REQUEST)

EasyMock.verify(tracer, spanContext)
tags.get("request-blob") should equal ("remote-service_span-name_1234567890_request")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.expedia.www.haystack.client

import java.util

object MockSpanBuilder {
def mockSpan(tracer: Tracer, clock: Clock, operationName: String, context: SpanContext,
startTime: Long, tags: util.Map[String, Object], references: util.List[Reference]) : Span = {
new Span(tracer, clock, "span-name", context,
System.currentTimeMillis(), tags, new util.ArrayList[Reference])
}
}
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<module>stores</module>
<module>agent</module>
<module>haystack-blobs</module>
<module>zipkin-blobs</module>
</modules>

<scm>
Expand Down
140 changes: 140 additions & 0 deletions zipkin-blobs/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>blobs</artifactId>
<groupId>com.expedia.www</groupId>
<version>1.1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>zipkin-blobs</artifactId>
<packaging>jar</packaging>

<properties>
<zipkin.version>5.9.0</zipkin.version>
</properties>

<dependencies>
<dependency>
<groupId>com.expedia.www</groupId>
<artifactId>blobs-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave</artifactId>
<version>${zipkin.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>

<!-- test -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_${scala.major.minor.version}</artifactId>
</dependency>
<dependency>
<groupId>org.pegdown</groupId>
<artifactId>pegdown</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.scalatest</groupId>
<artifactId>scalatest-maven-plugin</artifactId>
<executions>
<execution>
<id>test</id>
<goals>
<goal>test</goal>
</goals>
<configuration>
<tagsToExclude>com.expedia.test.IntegrationSuite</tagsToExclude>
</configuration>
</execution>
<execution>
<id>integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<tagsToInclude>com.expedia.test.IntegrationSuite</tagsToInclude>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
</plugin>

<plugin>
<groupId>org.scalastyle</groupId>
<artifactId>scalastyle-maven-plugin</artifactId>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>

<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<haltOnFailure>true</haltOnFailure>
<rules>
<rule>
<element>CLASS</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.00</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</plugin>
</plugins>
</build>

</project>
62 changes: 62 additions & 0 deletions zipkin-blobs/src/main/java/brave/blobs/SpanBlobContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package brave.blobs;

import brave.Span;
import com.expedia.blobs.core.BlobContext;
import com.expedia.blobs.core.BlobType;
import com.expedia.blobs.core.BlobWriter;
import org.apache.commons.lang3.Validate;

/**
* Class representing a {@link BlobContext} associated with {@link BlobWriter} and uses {@link Span}
* to save blob key produced to be used again for reading
*/

public class SpanBlobContext implements BlobContext {

private final Span span;
private final String remoteServiceName;
private final static String PARTIAL_BLOB_KEY = "-blob";
private final String name;

/**
* constructor
* @param span span object
* @param remoteServiceName for a specific service name, can't be null or empty
* @param name for a specific operation name
*/
public SpanBlobContext(Span span, String remoteServiceName, String name) {
Validate.notNull(span, "span cannot be null in context");
Validate.notEmpty(remoteServiceName, "remoteServiceName name cannot be null or empty in context");
Validate.notEmpty(name, "name cannot be null or empty in context");

this.span = span;
this.remoteServiceName = remoteServiceName;
this.name = name;
}

@Override
public String getOperationName() {
return this.name;
}

@Override
public String getServiceName() {
return this.remoteServiceName;
}

@Override
public String getOperationId() {
return String.valueOf(this.span.context().spanId());
}

/**
* This will be used to add the key produced inside the span
* for it to be used during the time of reading the blob through the span
* @param blobKey created from {@link SpanBlobContext#makeKey(BlobType)}
* @param blobType value of {@link BlobType}
*/
@Override
public void onBlobKeyCreate(String blobKey, BlobType blobType) {
span.tag(String.format("%s%s", blobType.getType(), PARTIAL_BLOB_KEY), blobKey);
}
}
55 changes: 55 additions & 0 deletions zipkin-blobs/src/test/scala/brave/blobs/SpanBlobContextSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package brave.blobs

import brave.Span
import brave.propagation.TraceContext
import com.expedia.blobs.core.BlobType
import org.easymock.EasyMock.{replay, verify}
import org.scalatest.easymock.EasyMockSugar
import org.scalatest.{FunSpec, Matchers}

class SpanBlobContextSpec extends FunSpec with Matchers with EasyMockSugar {

describe("brave.blobs.SpanBlobContext") {

it("should throw an error if span is not present") {
val catchExpection = intercept[Exception] {
val _ = new SpanBlobContext(null, "", "")
}

catchExpection.getMessage shouldEqual "span cannot be null in context"
}

it("should throw an error if serviceName is not present") {
val catchExpection = intercept[Exception] {
val _ = new SpanBlobContext(mock[Span], "", "")
}

catchExpection.getMessage shouldEqual "remoteServiceName name cannot be null or empty in context"
}

it("should throw an error if name is not present") {
val catchExpection = intercept[Exception] {
val _ = new SpanBlobContext(mock[Span], "remote-service", "")
}

catchExpection.getMessage shouldEqual "name cannot be null or empty in context"
}

it("should add a tag to the Span when onBlobKeyCreate is invoked") {
val span = mock[Span]
val traceContext = TraceContext.newBuilder().traceId(2345678901L).spanId(1234567890L).build()
val spanBlobContext = new SpanBlobContext(span, "remote-service", "span-name")

expecting {
span.tag("request-blob", "remote-service_span-name_1234567890_request").andReturn(span).once()
span.context().andReturn(traceContext).once()
}
replay(span)


spanBlobContext.onBlobKeyCreate(spanBlobContext.makeKey(BlobType.REQUEST), BlobType.REQUEST)

verify(span)
}
}
}

0 comments on commit 734fc22

Please sign in to comment.