blob: 6ab9fe63d82267a086d5e5c493b94bf5d6c9185e [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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.
//
use crate::trace::propagation::context::PropagationContext;
use base64::decode;
/// Decode context value packed in `sw8` header.
pub fn decode_propagation(header_value: &str) -> crate::Result<PropagationContext> {
let pieces: Vec<&str> = header_value.split('-').collect();
if pieces.len() != 8 {
return Err(crate::Error::DecodePropagation(
"failed to parse propagation context: it must have 8 properties.",
));
}
let do_sample = try_parse_sample_status(pieces[0])?;
let parent_trace_id = b64_encoded_into_string(pieces[1])?;
let parent_trace_segment_id = b64_encoded_into_string(pieces[2])?;
let parent_span_id: i32 = try_parse_parent_span_id(pieces[3])?;
let parent_service = b64_encoded_into_string(pieces[4])?;
let parent_service_instance = b64_encoded_into_string(pieces[5])?;
let destination_endpoint = b64_encoded_into_string(pieces[6])?;
let destination_address = b64_encoded_into_string(pieces[7])?;
let context = PropagationContext::new(
do_sample,
parent_trace_id,
parent_trace_segment_id,
parent_span_id,
parent_service,
parent_service_instance,
destination_endpoint,
destination_address,
);
Ok(context)
}
fn try_parse_parent_span_id(id: &str) -> crate::Result<i32> {
if let Ok(result) = id.parse::<i32>() {
Ok(result)
} else {
Err(crate::Error::DecodePropagation(
"failed to parse span id from parent.",
))
}
}
fn try_parse_sample_status(status: &str) -> crate::Result<bool> {
if status == "0" {
Ok(false)
} else if status == "1" {
Ok(true)
} else {
Err(crate::Error::DecodePropagation(
"failed to parse sample status.",
))
}
}
fn b64_encoded_into_string(enc: &str) -> crate::Result<String> {
if let Ok(result) = decode(enc) {
if let Ok(decoded_str) = String::from_utf8(result) {
return Ok(decoded_str);
}
}
Err(crate::Error::DecodePropagation("failed to decode value."))
}