Skip to content

Commit 3b3adb3

Browse files
authored
fix(attachments): Serialize ID without hyphens (#5501)
1 parent 47e6819 commit 3b3adb3

File tree

4 files changed

+68
-18
lines changed

4 files changed

+68
-18
lines changed

relay-event-schema/src/protocol/trace_attachment.rs

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
use relay_protocol::{Annotated, Empty, FromValue, IntoValue, Object, Value};
1+
use std::fmt;
2+
use std::ops::Deref;
3+
4+
use relay_protocol::{Annotated, Empty, FromValue, IntoValue, Object, SkipSerialization, Value};
5+
use serde::Serializer;
26

37
use crate::processor::ProcessValue;
48
use crate::protocol::{Attributes, Timestamp, TraceId};
@@ -14,7 +18,7 @@ pub struct TraceAttachmentMeta {
1418

1519
/// Unique identifier for this attachment.
1620
#[metastructure(required = true, nonempty = true, trim = false)]
17-
pub attachment_id: Annotated<Uuid>,
21+
pub attachment_id: Annotated<AttachmentId>,
1822

1923
/// Timestamp when the attachment was created.
2024
#[metastructure(required = true, trim = false)]
@@ -36,3 +40,50 @@ pub struct TraceAttachmentMeta {
3640
#[metastructure(additional_properties, pii = "maybe")]
3741
pub other: Object<Value>,
3842
}
43+
44+
#[derive(Clone, Default, PartialEq, Empty, FromValue, ProcessValue)]
45+
pub struct AttachmentId(Uuid);
46+
47+
impl AttachmentId {
48+
/// Creates a new attachment ID. Only used in tests.
49+
pub fn random() -> Self {
50+
Self(Uuid::now_v7())
51+
}
52+
}
53+
54+
impl Deref for AttachmentId {
55+
type Target = Uuid;
56+
57+
fn deref(&self) -> &Self::Target {
58+
&self.0
59+
}
60+
}
61+
62+
impl fmt::Display for AttachmentId {
63+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64+
write!(f, "{}", self.0.as_simple())
65+
}
66+
}
67+
68+
impl fmt::Debug for AttachmentId {
69+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70+
write!(f, "AttachmentId(\"{}\")", self.0.as_simple())
71+
}
72+
}
73+
74+
impl IntoValue for AttachmentId {
75+
fn into_value(self) -> Value
76+
where
77+
Self: Sized,
78+
{
79+
Value::String(self.to_string())
80+
}
81+
82+
fn serialize_payload<S>(&self, s: S, _behavior: SkipSerialization) -> Result<S::Ok, S::Error>
83+
where
84+
Self: Sized,
85+
S: Serializer,
86+
{
87+
s.collect_str(self)
88+
}
89+
}

relay-server/src/processing/trace_attachments/process.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,9 @@ pub fn scrub_attachment<'a>(
168168

169169
#[cfg(test)]
170170
mod tests {
171-
use relay_event_schema::protocol::TraceAttachmentMeta;
171+
use relay_event_schema::protocol::{AttachmentId, TraceAttachmentMeta};
172172
use relay_pii::PiiConfig;
173173
use relay_protocol::SerializableAnnotated;
174-
use uuid::Uuid;
175174

176175
use crate::envelope::ParentId;
177176
use crate::services::projects::project::ProjectInfo;
@@ -189,7 +188,7 @@ mod tests {
189188
let mut attachment = ExpandedAttachment {
190189
parent_id: None,
191190
meta: Annotated::new(TraceAttachmentMeta {
192-
attachment_id: Annotated::new(Uuid::new_v4()),
191+
attachment_id: Annotated::new(AttachmentId::random()),
193192
filename: Annotated::new("data.txt".to_owned()),
194193
content_type: Annotated::new("text/plain".to_owned()),
195194
..Default::default()
@@ -235,7 +234,7 @@ mod tests {
235234
let mut attachment = ExpandedAttachment {
236235
parent_id: Some(ParentId::SpanId(None)),
237236
meta: Annotated::new(TraceAttachmentMeta {
238-
attachment_id: Annotated::new(Uuid::new_v4()),
237+
attachment_id: Annotated::new(AttachmentId::random()),
239238
filename: Annotated::new("data.txt".to_owned()),
240239
content_type: Annotated::new("text/plain".to_owned()),
241240
attributes: Annotated::new(attributes),

relay-server/src/services/upload.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ impl UploadServiceInner {
336336
let key = Uuid::from_slice(&trace_item.trace_item.item_id)
337337
.map_err(Error::from)
338338
.reject(&trace_item)?
339+
.as_simple()
339340
.to_string();
340341

341342
#[cfg(debug_assertions)]

tests/integration/test_attachmentsv2.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
def create_attachment_metadata():
2525
return {
2626
"trace_id": uuid.uuid4().hex,
27-
"attachment_id": str(uuid.uuid4()),
27+
"attachment_id": uuid.uuid4().hex,
2828
"timestamp": 1760520026.781239,
2929
"filename": "myfile.txt",
3030
"content_type": "text/plain",
@@ -37,7 +37,6 @@ def create_attachment_metadata():
3737
def create_attachment_envelope(project_config):
3838
return Envelope(
3939
headers={
40-
"event_id": "515539018c9b4260a6f999572f1661ee",
4140
"trace": {
4241
"trace_id": "5b8efff798038103d269b633813fc60c",
4342
"public_key": project_config["publicKeys"][0]["publicKey"],
@@ -203,7 +202,7 @@ def test_standalone_attachment_store(
203202
),
204203
pytest.param(
205204
{"meta_length": None},
206-
273,
205+
269,
207206
"invalid_trace_attachment",
208207
id="missing_meta_length",
209208
),
@@ -341,9 +340,9 @@ def test_attachment_with_matching_span(mini_sentry, relay):
341340
assert attachment.payload.bytes == combined_payload
342341
assert attachment.headers == {
343342
"type": "attachment",
344-
"length": 260,
343+
"length": 256,
345344
"content_type": "application/vnd.sentry.trace-attachment",
346-
"meta_length": 237,
345+
"meta_length": 233,
347346
"span_id": span_id,
348347
}
349348

@@ -544,9 +543,9 @@ def test_two_attachments_mapping_to_same_span(mini_sentry, relay):
544543
assert item.payload.bytes == combined_payload
545544
assert item.headers == {
546545
"type": "attachment",
547-
"length": 260,
546+
"length": 256,
548547
"content_type": "application/vnd.sentry.trace-attachment",
549-
"meta_length": 237,
548+
"meta_length": 233,
550549
"span_id": span_id,
551550
}
552551

@@ -1260,7 +1259,7 @@ def test_attachment_default_pii_scrubbing_meta(
12601259
)
12611260

12621261
metadata = {
1263-
"attachment_id": str(uuid.uuid4()),
1262+
"attachment_id": uuid.uuid4().hex,
12641263
"timestamp": ts.timestamp(),
12651264
"filename": "data.txt",
12661265
"content_type": "text/plain",
@@ -1304,7 +1303,7 @@ def test_attachment_default_pii_scrubbing_meta(
13041303
metadata_part = json.loads(payload[:meta_length].decode("utf-8"))
13051304

13061305
assert metadata_part == {
1307-
"attachment_id": mock.ANY,
1306+
"attachment_id": metadata["attachment_id"],
13081307
"timestamp": time_within_delta(ts),
13091308
"filename": "data.txt",
13101309
"content_type": "text/plain",
@@ -1364,7 +1363,7 @@ def test_attachment_pii_scrubbing_meta_attribute(
13641363
)
13651364

13661365
metadata = {
1367-
"attachment_id": str(uuid.uuid4()),
1366+
"attachment_id": uuid.uuid4().hex,
13681367
"timestamp": ts.timestamp(),
13691368
"filename": "data.txt",
13701369
"content_type": "text/plain",
@@ -1398,7 +1397,7 @@ def test_attachment_pii_scrubbing_meta_attribute(
13981397
metadata_part = json.loads(payload[:meta_length].decode("utf-8"))
13991398

14001399
assert metadata_part == {
1401-
"attachment_id": mock.ANY,
1400+
"attachment_id": metadata["attachment_id"],
14021401
"timestamp": time_within_delta(ts),
14031402
"filename": "data.txt",
14041403
"content_type": "text/plain",
@@ -1455,7 +1454,7 @@ def test_attachment_pii_scrubbing_body(mini_sentry, relay):
14551454
)
14561455

14571456
metadata = {
1458-
"attachment_id": str(uuid.uuid4()),
1457+
"attachment_id": uuid.uuid4().hex,
14591458
"timestamp": ts.timestamp(),
14601459
"filename": "log.txt",
14611460
"content_type": "text/plain",

0 commit comments

Comments
 (0)