Repository: open-telemetry/opentelemetry-python

Issue:
opentracing shim not connecting "follows from" relationship properly
**Describe your environment** 
The environment can be fully reproduced with [this project](https://github.com/robertsben/otel-example/tree/follows-from-ref). Python 3, opentelemetry 1.5.0, shim 0.24b0.

**Steps to reproduce**
To reproduce the problem you need to create a `follows_from` relationship trace, like you would find in a pub sub application architecture, and see how there is only a link in opentelemetry, where opentracing treats the link more like a weak child.

A minimal working example is provided [here](https://github.com/robertsben/otel-example/tree/follows-from-ref).

**What is the expected behavior?**
You would expect to see a follows from trace (in opentracing) looking like this, in the Jaeger UI:
![Screenshot 2021-10-05 at 15 01 08](https://user-images.githubusercontent.com/9368996/136038661-1bead63a-91f4-466b-89c4-053b58fb2ae4.png)

**What is the actual behavior?**
Instead, with opentelemetry (and the shim), you get a weak link that doesn't display the traces together:
![Screenshot 2021-10-05 at 15 02 32](https://user-images.githubusercontent.com/9368996/136038776-e5f8865e-0760-43cd-b368-8602c7067d49.png)
![Screenshot 2021-10-05 at 15 02 45](https://user-images.githubusercontent.com/9368996/136038786-468b4857-98ef-43f6-b153-465d6fd13aea.png)

**Additional context**
In the python jaeger-client the relationship between follows from traces is treated as a weak parental relationship [deliberately](https://github.com/jaegertracing/jaeger-client-python/blob/ba852035775475effa23676c100315e73453df12/jaeger_client/tracer.py#L179).



Discussion:

Resolving patch:
diff --git a/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py b/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py
--- a/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py
+++ b/shim/opentelemetry-opentracing-shim/src/opentelemetry/shim/opentracing_shim/__init__.py
@@ -592,7 +592,10 @@ def start_active_span(
 
         current_span = get_current_span()
 
-        if child_of is None and current_span is not INVALID_SPAN_CONTEXT:
+        if (
+            child_of is None
+            and current_span.get_span_context() is not INVALID_SPAN_CONTEXT
+        ):
             child_of = SpanShim(None, None, current_span)
 
         span = self.start_span(
@@ -649,12 +652,16 @@ def start_span(
         if isinstance(parent, OtelSpanContext):
             parent = NonRecordingSpan(parent)
 
-        parent_span_context = set_span_in_context(parent)
-
-        links = []
+        valid_links = []
         if references:
             for ref in references:
-                links.append(Link(ref.referenced_context.unwrap()))
+                if ref.referenced_context.unwrap() is not INVALID_SPAN_CONTEXT:
+                    valid_links.append(Link(ref.referenced_context.unwrap()))
+
+        if valid_links and parent is None:
+            parent = NonRecordingSpan(valid_links[0].context)
+
+        parent_span_context = set_span_in_context(parent)
 
         # The OpenTracing API expects time values to be `float` values which
         # represent the number of seconds since the epoch. OpenTelemetry
@@ -666,7 +673,7 @@ def start_span(
         span = self._otel_tracer.start_span(
             operation_name,
             context=parent_span_context,
-            links=links,
+            links=valid_links,
             attributes=tags,
             start_time=start_time_ns,
         )


Test patch:
diff --git a/shim/opentelemetry-opentracing-shim/tests/test_shim.py b/shim/opentelemetry-opentracing-shim/tests/test_shim.py
--- a/shim/opentelemetry-opentracing-shim/tests/test_shim.py
+++ b/shim/opentelemetry-opentracing-shim/tests/test_shim.py
@@ -389,6 +389,24 @@ def test_references(self):
                     parent.context.unwrap(),
                 )
 
+    def test_follows_from_references(self):
+        """Test span creation using the `references` argument with a follows from relationship."""
+
+        with self.shim.start_span("ParentSpan") as parent:
+            ref = opentracing.follows_from(parent.context)
+
+        with self.shim.start_active_span(
+            "FollowingSpan", references=[ref]
+        ) as child:
+            self.assertEqual(
+                child.span.unwrap().links[0].context,
+                parent.context.unwrap(),
+            )
+            self.assertEqual(
+                child.span.unwrap().parent,
+                parent.context.unwrap(),
+            )
+
     def test_set_operation_name(self):
         """Test `set_operation_name()` method."""