Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Commit

Permalink
Merge c1a568e into b9feb48
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosalberto committed Nov 28, 2017
2 parents b9feb48 + c1a568e commit 9126044
Show file tree
Hide file tree
Showing 61 changed files with 5,125 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright 2016-2017 The OpenTracing Authors
*
* 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 io.opentracing.util;

import io.opentracing.Scope;
import io.opentracing.Span;

import java.util.concurrent.atomic.AtomicInteger;

public class AutoFinishScope implements Scope {
final AutoFinishScopeManager manager;
final AtomicInteger refCount;
private final Span wrapped;
private final AutoFinishScope toRestore;

AutoFinishScope(AutoFinishScopeManager manager, AtomicInteger refCount, Span wrapped) {
this.manager = manager;
this.refCount = refCount;
this.wrapped = wrapped;
this.toRestore = manager.tlsScope.get();
manager.tlsScope.set(this);
}

public class Continuation {
public Continuation() {
refCount.incrementAndGet();
}

public AutoFinishScope activate() {
return new AutoFinishScope(manager, refCount, wrapped);
}
}

public Continuation capture() {
return new Continuation();
}

@Override
public void close() {
if (manager.tlsScope.get() != this) {
return;
}

if (refCount.decrementAndGet() == 0) {
wrapped.finish();
}

manager.tlsScope.set(toRestore);
}

@Override
public Span span() {
return wrapped;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2016-2017 The OpenTracing Authors
*
* 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 io.opentracing.util;

import io.opentracing.ScopeManager;
import io.opentracing.Span;

import java.util.concurrent.atomic.AtomicInteger;

public class AutoFinishScopeManager implements ScopeManager {
final ThreadLocal<AutoFinishScope> tlsScope = new ThreadLocal<AutoFinishScope>();

@Override
public AutoFinishScope activate(Span span) {
return new AutoFinishScope(this, new AtomicInteger(1), span);
}

@Override
public AutoFinishScope activate(Span span, boolean finishOnClose) {
return new AutoFinishScope(this, new AtomicInteger(1), span);
}

@Override
public AutoFinishScope active() {
return tlsScope.get();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright 2016-2017 The OpenTracing Authors
*
* 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 io.opentracing.util;

import io.opentracing.Scope;
import io.opentracing.Span;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

public class AutoFinishScopeManagerTest {
private AutoFinishScopeManager source;
@Before
public void before() throws Exception {
source = new AutoFinishScopeManager();
}

@Test
public void missingScope() throws Exception {
Scope missingSpan = source.active();
assertNull(missingSpan);
}

@Test
public void activateSpan() throws Exception {
Span span = mock(Span.class);

// We can't use 1.7 features like try-with-resources in this repo without meddling with pom details for tests.
Scope active = source.activate(span);
try {
assertNotNull(active);
Scope otherScope = source.active();
assertEquals(otherScope, active);
} finally {
active.close();
}

// Make sure the Span got finish()ed.
verify(span).finish();

// And now it's gone:
Scope missingSpan = source.active();
assertNull(missingSpan);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright 2016-2017 The OpenTracing Authors
*
* 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 io.opentracing.util;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import io.opentracing.Scope;
import io.opentracing.Span;
import org.junit.Before;
import org.junit.Test;

public class AutoFinishScopeTest {
private AutoFinishScopeManager manager;

@Before
public void before() throws Exception {
manager = new AutoFinishScopeManager();
}

@Test
public void continuation() throws Exception {
Span span = mock(Span.class);

// Quasi try-with-resources (this is 1.6).
AutoFinishScope active = (AutoFinishScope)manager.activate(span);
AutoFinishScope.Continuation continued = null;
try {
assertNotNull(active);
continued = active.capture();
} finally {
active.close();
}

// Make sure the Span was not finished since there was a capture().
verify(span, never()).finish();

// Activate the continuation.
try {
active = continued.activate();
} finally {
active.close();
}

// Now the Span should be finished.
verify(span, times(1)).finish();

// And now it's no longer active.
Scope missingSpan = manager.active();
assertNull(missingSpan);
}

@Test
public void implicitSpanStack() throws Exception {
Span backgroundSpan = mock(Span.class);
Span foregroundSpan = mock(Span.class);

// Quasi try-with-resources (this is 1.6).
Scope backgroundActive = manager.activate(backgroundSpan);
try {
assertNotNull(backgroundActive);

// Activate a new Scope on top of the background one.
Scope foregroundActive = manager.activate(foregroundSpan);
try {
Scope shouldBeForeground = manager.active();
assertEquals(foregroundActive, shouldBeForeground);
} finally {
foregroundActive.close();
}

// And now the backgroundActive should be reinstated.
Scope shouldBeBackground = manager.active();
assertEquals(backgroundActive, shouldBeBackground);
} finally {
backgroundActive.close();
}

// The background and foreground Spans should be finished.
verify(backgroundSpan, times(1)).finish();
verify(foregroundSpan, times(1)).finish();

// And now nothing is active.
Scope missingSpan = manager.active();
assertNull(missingSpan);
}

@Test
public void testDeactivateWhenDifferentSpanIsActive() {
Span span = mock(Span.class);

Scope active = manager.activate(span);
manager.activate(mock(Span.class));
active.close();

verify(span, times(0)).finish();
}
}
69 changes: 69 additions & 0 deletions opentracing-v030/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# OpenTracing-Java 0.30 compatibility layer.

The `opentracing-v030` artifact provides a 0.30 API compatibility layer which comprises:
1. Exposing all the the 0.30 packages under `io.opentracing.v_030` (`io.opentracing.v_030.propagation`, `io.opentracing.v_30.util`, etc).
2. A Shim layer to wrap 0.31 Tracer and expose it under the 0.30 API.

## Shim Layer

The basic shim layer is exposed through `TracerShim`, which wraps a `io.opentracing.Tracer` object and exposes it under the `io.opentracing.v_030.Tracer` interface:

```java
import io.opentracing.v_030.ActiveSpan;
import io.opentracing.v_030.Tracer;
import io.opentracing.v_030.shim.TracerShim;
```

For `ActiveSpan.capture()` and `Continuation`s support, the usage of `io.opentracing.util.AutoFinishScopeManager` as `Tracer.scopeManager()` is required (which preserves the reference-count system used in 0.30).

```java
import io.opentracing.util.AutoFinishScopeManager;
import io.opentracing.v_030.ActiveSpan;
import io.opentracing.v_030.Tracer;
import io.opentracing.v_030.shim.AutoFinishTracerShim;

io.opentracing.Tracer upstreamTracer = new CustomTracer(..., new AutoFinishScopeManager());
Tracer tracer = new TracerShim(yourUpstreamTracer);

try (ActiveSpan span = tracer.buildSpan("parent").startActive()) {
ActiveSpan.Continuation cont = span.capture();
...
}
```

## Extending the Shim layer

When the Shim layer is required without the reference-count system, it's possible to provide a custom class extending `BaseTracerShim`, which will need to provide a custom `ActiveSpanShim` instance upong `Span` activation:

```java
import io.opentracing.util.AutoFinishScopeManager;
import io.opentracing.v_030.ActiveSpan;
import io.opentracing.v_030.Tracer;
import io.opentracing.v_030.shim.AutoFinishTracerShim;


public class CustomTracerShim extends BaseTracerShim {
public CustomTracerShim(io.opentracing.Tracer tracer) {
super(tracer);
}

@Override
public ActiveSpanShim createActiveSpanShim(Scope scope) {
return CustomActiveSpanShim(scope);
}

static final class CustomActiveSpanShim extends ActiveSpanShim {
public CustomActiveSpanShim(Scope scope) {
super(scope);
}

@Override
public Continuation capture() {
...
}
}
}
```

The returned `ActiveSpanShim` instance must react properly to `ActiveSpan.capture()` and return a `ActiveSpan.Continuation` object than can later be reactivated. Observe the default implementation of `ActiveSpanShim.capture()` throws `UnsupportedOperationException`.

Loading

0 comments on commit 9126044

Please sign in to comment.