Skip to content

Commit 3da68e8

Browse files
committed
test to use shaded util, instead of client
1 parent 1036b35 commit 3da68e8

File tree

4 files changed

+131
-17
lines changed

4 files changed

+131
-17
lines changed

instrumentation/grpc-1.6/build.gradle.kts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ muzzle {
1515
group = "io.grpc"
1616
module = "grpc-core"
1717
versions = "[1.6.0,)"
18-
// for body capture via com.google.protobuf.Message to exist always
19-
extraDependency("com.google.protobuf:protobuf-java:3.3.1")
18+
2019
extraDependency("io.grpc:grpc-netty:1.6.0")
2120
}
2221
}

instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/GrpcSpanDecorator.java

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,16 @@
1616

1717
package io.opentelemetry.javaagent.instrumentation.hypertrace.grpc.v1_6;
1818

19-
import com.google.protobuf.Message;
2019
import io.grpc.Metadata;
2120
import io.grpc.Metadata.Key;
2221
import io.opentelemetry.api.common.AttributeKey;
2322
import io.opentelemetry.api.trace.Span;
2423
import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.util.JsonFormat;
2524
import io.opentelemetry.javaagent.instrumentation.hypertrace.grpc.GrpcSemanticAttributes;
26-
import java.io.IOException;
2725
import java.util.LinkedHashMap;
2826
import java.util.Map;
2927
import java.util.function.Function;
3028
import org.hypertrace.agent.core.instrumentation.HypertraceSemanticAttributes;
31-
import org.hypertrace.agent.core.instrumentation.buffer.BoundedBuffersFactory;
32-
import org.hypertrace.agent.core.instrumentation.buffer.BoundedCharArrayWriter;
3329
import org.slf4j.Logger;
3430
import org.slf4j.LoggerFactory;
3531

@@ -41,14 +37,11 @@ private GrpcSpanDecorator() {}
4137
private static final JsonFormat.Printer PRINTER = JsonFormat.printer();
4238

4339
public static void addMessageAttribute(Object message, Span span, AttributeKey<String> key) {
44-
if (message instanceof Message) {
45-
Message mb = (Message) message;
40+
if (isProtobufMessage(message)) {
4641
try {
47-
BoundedCharArrayWriter writer = BoundedBuffersFactory.createWriter();
48-
PRINTER.appendTo(mb, writer);
49-
span.setAttribute(key, writer.toString());
50-
} catch (IOException e) {
51-
log.error("Failed to decode message to JSON", e);
42+
ProtobufRoundTripConverter.addConvertedMessageAttribute(message, span, key);
43+
} catch (Exception e) {
44+
log.error("Failed to print message as JSON", e);
5245
}
5346
}
5447
}
@@ -90,4 +83,21 @@ public static Map<String, String> metadataToMap(Metadata metadata) {
9083
}
9184
return mapHeaders;
9285
}
86+
87+
private static boolean isProtobufMessage(Object message) {
88+
if (message == null) {
89+
return false;
90+
}
91+
// Check the interfaces on the class and its superclasses
92+
Class<?> cls = message.getClass();
93+
while (cls != null) {
94+
for (Class<?> iface : cls.getInterfaces()) {
95+
if ("com.google.protobuf.Message".equals(iface.getName())) {
96+
return true;
97+
}
98+
}
99+
cls = cls.getSuperclass();
100+
}
101+
return false;
102+
}
93103
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright The Hypertrace Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.opentelemetry.javaagent.instrumentation.hypertrace.grpc.v1_6;
18+
19+
import com.google.protobuf.Descriptors;
20+
import com.google.protobuf.Message;
21+
import io.opentelemetry.api.common.AttributeKey;
22+
import io.opentelemetry.api.trace.Span;
23+
import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.DescriptorProtos.FileDescriptorProto;
24+
import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Descriptors.Descriptor;
25+
import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Descriptors.FileDescriptor;
26+
import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.DynamicMessage;
27+
import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.util.JsonFormat;
28+
29+
public class ProtobufRoundTripConverter {
30+
31+
/**
32+
* Converts an unrelocated protobuf message into a relocated DynamicMessage via a byte-array
33+
* round-trip.
34+
*
35+
* @param message The original protobuf message (an instance of com.google.protobuf.Message).
36+
* @return A relocated DynamicMessage built from your relocated protobuf classes.
37+
* @throws Exception if conversion fails.
38+
*/
39+
public static DynamicMessage convertToRelocatedDynamicMessage(Object message) throws Exception {
40+
if (!(message instanceof Message)) {
41+
throw new IllegalArgumentException("message is not a protobuf Message");
42+
}
43+
// 1. Serialize the original message to bytes.
44+
Message originalMessage = (Message) message;
45+
byte[] messageBytes = originalMessage.toByteArray();
46+
47+
// 2. Obtain the original (unrelocated) message descriptor.
48+
Descriptors.Descriptor originalDescriptor = originalMessage.getDescriptorForType();
49+
50+
// 3. Get the unrelocated file descriptor and its proto representation.
51+
Descriptors.FileDescriptor unrelocatedFileDescriptor = originalDescriptor.getFile();
52+
com.google.protobuf.DescriptorProtos.FileDescriptorProto unrelocatedFileProto =
53+
unrelocatedFileDescriptor.toProto();
54+
byte[] fileProtoBytes = unrelocatedFileProto.toByteArray();
55+
56+
// 4. Parse the file descriptor proto using relocated classes.
57+
// This converts the unrelocated FileDescriptorProto into your relocated FileDescriptorProto.
58+
FileDescriptorProto relocatedFileProto = FileDescriptorProto.parseFrom(fileProtoBytes);
59+
60+
// 5. Build the relocated FileDescriptor.
61+
// Note: This example assumes there are no dependencies.
62+
FileDescriptor relocatedFileDescriptor =
63+
FileDescriptor.buildFrom(relocatedFileProto, new FileDescriptor[] {});
64+
65+
// 6. Find the relocated message descriptor by name.
66+
// We assume the message name is the same in both relocated and unrelocated files.
67+
Descriptor relocatedDescriptor =
68+
relocatedFileDescriptor.findMessageTypeByName(originalDescriptor.getName());
69+
if (relocatedDescriptor == null) {
70+
throw new IllegalStateException(
71+
"Could not find relocated descriptor for message type: " + originalDescriptor.getName());
72+
}
73+
74+
// 7. Parse the original message bytes using the relocated descriptor.
75+
DynamicMessage relocatedMessage = DynamicMessage.parseFrom(relocatedDescriptor, messageBytes);
76+
return relocatedMessage;
77+
}
78+
79+
/**
80+
* Example method that takes an incoming message, converts it to a relocated one, prints it as
81+
* JSON using the relocated JsonFormat, and attaches it as a span attribute.
82+
*
83+
* @param message The incoming (unrelocated) protobuf message.
84+
* @param span The span to which to attach the attribute.
85+
* @param key The attribute key.
86+
*/
87+
public static void addConvertedMessageAttribute(
88+
Object message, Span span, AttributeKey<String> key) {
89+
try {
90+
// Convert the unrelocated message into a relocated DynamicMessage.
91+
DynamicMessage relocatedMessage = convertToRelocatedDynamicMessage(message);
92+
93+
// Use the relocated JsonFormat to print the message as JSON.
94+
JsonFormat.Printer relocatedPrinter = JsonFormat.printer();
95+
String jsonOutput = relocatedPrinter.print(relocatedMessage);
96+
97+
// Set the JSON output as a span attribute.
98+
span.setAttribute(key, jsonOutput);
99+
} catch (Exception e) {
100+
System.err.println("Failed to convert message via byte-array round-trip: " + e.getMessage());
101+
e.printStackTrace();
102+
}
103+
}
104+
}

shaded-protobuf-java-util/build.gradle.kts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@ plugins {
44
}
55

66
dependencies {
7-
implementation("com.google.protobuf:protobuf-java-util:3.25.5") {
8-
exclude("com.google.protobuf", "protobuf-java")
9-
exclude("com.google.guava", "guava")
10-
}
7+
implementation("com.google.protobuf:protobuf-java-util:3.25.5")
8+
119
// fix vulnerability
1210
constraints {
1311
implementation("com.google.code.gson:gson:2.8.9")
1412
}
1513
}
1614

1715
tasks.shadowJar {
16+
relocate("com.google.protobuf", "io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf")
1817
relocate("com.google.protobuf.util", "io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.util")
1918
relocate("com.google.gson", "io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.gson")
19+
relocate("com.google.common", "io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.common") // Add this
20+
relocate("com.google.guava", "io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.guava")
2021
}

0 commit comments

Comments
 (0)