@@ -111,4 +111,47 @@ SpanPtr TraceContexts::CreateChildSpanFromBinary(const std::string& trace_contex
111111 return opentracing::Tracer::Global ()->StartSpan (
112112 child_name, {opentracing::FollowsFrom (&**parent_span_context), opentracing::SetTag{kCorrelationIdTag , cid}});
113113}
114+
115+ struct GrpcMetadataCarrierForReading : opentracing::TextMapReader {
116+ GrpcMetadataCarrierForReading (const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata)
117+ : client_metadata_(client_metadata) {}
118+
119+ using F = std::function<opentracing::expected<void >(opentracing::string_view, opentracing::string_view)>;
120+
121+ opentracing::expected<void > ForeachKey (F f) const override {
122+ // Iterate through all key-value pairs, the tracer will use the relevant keys
123+ // to extract a span context.
124+ for (auto & key_value : client_metadata_) {
125+ auto was_successful = f (FromStringRef (key_value.first ), FromStringRef (key_value.second ));
126+ if (!was_successful) {
127+ // If the callback returns and unexpected value, bail out of the loop.
128+ return was_successful;
129+ }
130+ }
131+ // Indicate successful iteration.
132+ return {};
133+ }
134+
135+ opentracing::expected<opentracing::string_view> LookupKey (opentracing::string_view key) const override {
136+ auto find_it = client_metadata_.find (grpc::string_ref (key));
137+ if (find_it != client_metadata_.end ()) {
138+ return opentracing::make_unexpected (opentracing::key_not_found_error);
139+ }
140+ return opentracing::string_view{FromStringRef (find_it->second )};
141+ }
142+
143+ private:
144+ static std::string FromStringRef (const grpc::string_ref& string_ref) {
145+ return std::string (string_ref.data (), string_ref.size ());
146+ }
147+
148+ const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata_;
149+ };
150+
151+ TraceContexts::SpanCtxPtr TraceContexts::ExtractSpanFromMetadata (const opentracing::Tracer& tracer,
152+ const grpc::ServerContext& context) {
153+ GrpcMetadataCarrierForReading metadata_carrier (context.client_metadata ());
154+ return *tracer.Extract (metadata_carrier);
155+ }
156+
114157} // namespace client::thin_replica_client
0 commit comments