| // 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::ID; |
| |
| pub struct SegmentRef { |
| trace_id: ID, |
| segment_id: ID, |
| span_id: i32, |
| parent_service_instance_id: i32, |
| entry_service_instance_id: i32, |
| network_address: Option<String>, |
| network_address_id: i32, |
| entry_endpoint: Option<String>, |
| entry_endpoint_id: i32, |
| parent_endpoint: Option<String>, |
| parent_endpoint_id: i32, |
| } |
| |
| impl SegmentRef { |
| pub fn from_text(value: &str) -> Option<Self> { |
| let strings: Vec<&str> = value.split("-").collect(); |
| if strings.len() == 9 { |
| // Ignore string[0]. |
| let trace_id = match SegmentRef::string_to_id(strings[1]) { |
| Some(id) => { id } |
| _ => { return None; } |
| }; |
| let segment_id = match SegmentRef::string_to_id(strings[2]) { |
| Some(id) => { id } |
| _ => { return None; } |
| }; |
| let span_id = match strings[3].parse::<i32>() { |
| Ok(id) => { id } |
| _ => { return None; } |
| }; |
| let parent_service_instance_id = match strings[4].parse::<i32>() { |
| Ok(id) => { id } |
| _ => { return None; } |
| }; |
| let entry_service_instance_id = match strings[5].parse::<i32>() { |
| Ok(id) => { id } |
| _ => { return None; } |
| }; |
| |
| let (network_address, network_address_id) = match SegmentRef::decode_base64_to_string_or_id(strings[6]) { |
| Some(decoded) => { decoded } |
| _ => { return None; } |
| }; |
| let (entry_endpoint, entry_endpoint_id) = match SegmentRef::decode_base64_to_string_or_id(strings[7]) { |
| Some(decoded) => { decoded } |
| _ => { return None; } |
| }; |
| let (parent_endpoint, parent_endpoint_id) = match SegmentRef::decode_base64_to_string_or_id(strings[8]) { |
| Some(decoded) => { decoded } |
| _ => { return None; } |
| }; |
| |
| Some(SegmentRef { |
| trace_id, |
| segment_id, |
| span_id, |
| parent_service_instance_id, |
| entry_service_instance_id, |
| network_address, |
| network_address_id, |
| entry_endpoint, |
| entry_endpoint_id, |
| parent_endpoint, |
| parent_endpoint_id, |
| }) |
| } else { |
| None |
| } |
| } |
| |
| pub fn get_trace_id(&self) -> ID { |
| self.trace_id.clone() |
| } |
| |
| fn string_to_id(text: &str) -> Option<ID> { |
| match base64::decode(text) { |
| Ok(value) => { |
| match String::from_utf8(value) { |
| Ok(str) => { |
| match ID::from(str) { |
| Ok(id) => { Some(id) } |
| _ => None |
| } |
| } |
| _ => { None } |
| } |
| } |
| _ => { None } |
| } |
| } |
| |
| fn decode_base64_to_string_or_id(text: &str) -> Option<(Option<String>, i32)> { |
| match base64::decode(text) { |
| Ok(value) => { |
| match String::from_utf8(value) { |
| Ok(str) => { |
| if str.starts_with("#") { |
| let network: Vec<&str> = str.split("#").collect(); |
| (Some((Some(network[1].to_string()), 0))) |
| } else { |
| match str.parse::<i32>() { |
| Ok(id) => { Some((None, id)) } |
| _ => { None } |
| } |
| } |
| } |
| _ => { None } |
| } |
| } |
| _ => { None } |
| } |
| } |
| } |
| |
| #[cfg(test)] |
| mod segment_ref_tests { |
| use crate::ID; |
| use crate::segment_ref::SegmentRef; |
| |
| #[test] |
| fn test_deserialize_context_carrier() { |
| let carrier = SegmentRef::from_text("1-My40LjU=-MS4yLjM=-4-1-1-IzEyNy4wLjAuMTo4MDgw-Iy9wb3J0YWw=-MTIz").unwrap(); |
| assert_eq!(carrier.trace_id == ID::new(3, 4, 5), true); |
| assert_eq!(carrier.segment_id == ID::new(1, 2, 3), true); |
| assert_eq!(carrier.span_id, 4); |
| assert_eq!(carrier.entry_service_instance_id, 1); |
| assert_eq!(carrier.parent_service_instance_id, 1); |
| assert_eq!(carrier.network_address, Some("127.0.0.1:8080".to_string())); |
| assert_eq!(carrier.entry_endpoint, Some("/portal".to_string())); |
| assert_eq!(carrier.parent_endpoint_id, 123); |
| } |
| } |