[VOL-3196] Enhanced gRPC interfaces to create and propagate Span for log correlation

Change-Id: I8bbf2263a7090b73555027cc54ff5c55a66ee4fb
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/metadata.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/metadata.go
new file mode 100644
index 0000000..38f251d
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/metadata.go
@@ -0,0 +1,56 @@
+// Copyright 2017 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_opentracing
+
+import (
+	"encoding/base64"
+	"strings"
+
+	"fmt"
+
+	"google.golang.org/grpc/metadata"
+)
+
+const (
+	binHdrSuffix = "-bin"
+)
+
+// metadataTextMap extends a metadata.MD to be an opentracing textmap
+type metadataTextMap metadata.MD
+
+// Set is a opentracing.TextMapReader interface that extracts values.
+func (m metadataTextMap) Set(key, val string) {
+	// gRPC allows for complex binary values to be written.
+	encodedKey, encodedVal := encodeKeyValue(key, val)
+	// The metadata object is a multimap, and previous values may exist, but for opentracing headers, we do not append
+	// we just override.
+	m[encodedKey] = []string{encodedVal}
+}
+
+// ForeachKey is a opentracing.TextMapReader interface that extracts values.
+func (m metadataTextMap) ForeachKey(callback func(key, val string) error) error {
+	for k, vv := range m {
+		for _, v := range vv {
+			if decodedKey, decodedVal, err := metadata.DecodeKeyValue(k, v); err == nil {
+				if err = callback(decodedKey, decodedVal); err != nil {
+					return err
+				}
+			} else {
+				return fmt.Errorf("failed decoding opentracing from gRPC metadata: %v", err)
+			}
+		}
+	}
+	return nil
+}
+
+// encodeKeyValue encodes key and value qualified for transmission via gRPC.
+// note: copy pasted from private values of grpc.metadata
+func encodeKeyValue(k, v string) (string, string) {
+	k = strings.ToLower(k)
+	if strings.HasSuffix(k, binHdrSuffix) {
+		val := base64.StdEncoding.EncodeToString([]byte(v))
+		v = string(val)
+	}
+	return k, v
+}